Небольшой и, возможно, глупый вопрос по Си.
void f(void (**some_func)(void*)) {
(*some_func)(some_func);
}
...
struct {
void (*func_ptr)(void*);
...
} some_struct = { ... };
f((void (**)(void*))&some_struct);
Является ли приведённый выше код корректным?
По сути дела он базируется на двух предположениях:
1) Адрес первого поля структуры совпадает с адресом структуры. Пустые байты для выравнивания (если компилятор решил их добавить) всегда добавляются после поля, но не перед ним.
2) Указатель на указатель на функцию это самый обычный указатель на данные. Указатель на функцию сам по себе может быть особенным. Например, если речь идёт о гарвардской архитектуре, в которой код и данные имеют разные адресные пространства. Соответственно, указатель на функцию может быть чем-то принципиально иным, нежели указатель на данные (даже банально разрядности адресов в памяти программ и памяти данных могут быть разными). Но указатель на указатель на функцию это уже самое обычное число.
Верны ли эти предположения для всех архитектур, где имеет место быть Си?