特别是,以下内容将无法按预期工作:
typedef void(*func_p)(void*);
void foo(int* data)
{
printf("%i\n",*data);
}
int main(int argc, char** argv)
{
func_p bar;
int x = 42;
bar = foo;
bar((void*)&x);
return 0;
}
即,我是否可以依赖数据指针(void*
,int*
,struct baz*
,但不一定void(*)(void)
)始终以相应的方式传递?
答案 0 :(得分:7)
标准不要求这样做。标准要求char*
和void*
具有相同的表示和对齐要求,所有结构指针都这样做,并且所有联合指针也都这样做。虽然在任何情况下调用转换函数指针都是未定义的行为(§6.5.2.2p9),但相同的表示和对齐要求可以保证调用有效(§6.2.5p27)。
其他指针类型不需要以这种方式表现,尽管我没有亲自遇到过这样的机器。理论上,int*
的{{1}}可能比sizeof
小char*
,如果int
的对齐要求比char
更严格,这可能是合理的要做的事)。在正确的调用约定下,在这样的机器上,实际上不可能调用一个转换函数指针。
答案 1 :(得分:1)
除非您的代码针对奇怪的古代大型机,否则出于所有实际目的它将正常工作。没有现代机器对不同的指针类型使用不同的表示,我认为任何未来的机器都不会是现实的。它只是不合逻辑和倒退,就像补码算法一样。
如果您仍然担心或想要满足语言纯粹主义者,请按照caf的建议。