指向函数赋值的指针,C
我不明白为什么下面的代码会生成警告:
int func(double a, int b, char c)
{
return 0;
}
int main()
{
int(*myPointer)() = func;
return 0;
}
我认为在 C 中,具有空参数列表的函数意味着可以接收未知数量参数的函数。 func4 恰好接收 3 个参数。那么为什么它与 myPointer 不兼容呢?
它特别令人困惑,因为以下内容会在没有警告的情况下进行编译:
void boo()
{
return;
}
int main()
{
int(*pointerDude)(double) = boo;
return 0;
}
发生了什么事?
I don't understand why the following code generates a warning:
int func(double a, int b, char c)
{
return 0;
}
int main()
{
int(*myPointer)() = func;
return 0;
}
I thought that in C, a function with an empty parameters list mean a function that can receive an unknown number of parameters. func4 happens to receive 3 parameters. So why is it incompatible with myPointer?
Its especially confusing because the following does compile without warning:
void boo()
{
return;
}
int main()
{
int(*pointerDude)(double) = boo;
return 0;
}
What's going on?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这两种情况之间的区别可以这样解释:如果将参数传递给不接受任何参数的函数,那么您只是消耗了堆栈上的一些内存。如果您不将任何参数传递给接受一些参数的函数,则后者将从堆栈中读取随机数据。
更新:更改为社区 wiki,添加 Pascal Cuoq 的这些更正:
尽管编译器会发出警告,但函数指针在两个方向上的转换都是合法的、信息丰富的警告。在这两种情况下,调用具有错误原型的函数都是非法的。某些 ABI 要求函数清理堆栈,在这种情况下,将参数传递给不接受任何参数的函数,就像不将参数传递给需要参数的函数一样,肯定会破坏堆栈。
C99 6.3.2.3 段8:
The difference between the two cases is explained like this: if you pass a parameter to a function that accepts none, you are just consuming some memory on the stack. If you don't pass any parameter to a function that accepts a few, the latter is going to read random data from the stack.
Update: changed to community wiki to add these corrections from Pascal Cuoq:
Casts of function pointer in both directions are legal, informative warnings from the compiler notwithstanding. Calling a function with the wrong prototype is illegal in both cases. Some ABIs mandate that the function clean up the stack, in which case passing parameters to functions that accept none corrupt the stack as surely as not passing parameters to functions that expect them.
C99 6.3.2.3 par. 8:
这是您收到的警告:
您正在传递
void
,这意味着需要进行强制转换。您应该使用正确的类型。This is the warning you get:
You are passing
void
which means that will require a cast. You should use the right types.IIRC C 编译器有某些假设,这些假设可能会导致非常奇怪的错误,因为您没有告诉它每当调用该函数时它需要多少堆栈空间。特别是由于定义不匹配,这可能会让某人无意中读取您的函数指针声明并假设没有参数并使函数返回垃圾。如果您确实想采用可变数量的参数,请使用 my_func(...) 和 varargs。
IIRC C compiler has certain assumptions which can cause very odd bugs because you're not telling it how much stack space it needs whenever that function is called. Especially since the definitions don't match this might allow someone to inadvertently read your function pointer declaration and assume no parameters and have the function return garbage. If you really want to take variable numbers of parameters use my_func(...) and varargs.
警告就是警告。诚实的。
在这种情况下,编译器知道您的函数指针类型不正确,并且它会公然地告诉您这一点。如果您尝试传递多个参数而不是 3 个,则会发出错误。
A warning is just that, a warning. Honest.
In that case, the compiler knows you have an incorrect function pointer type and it blatantly tells you that. If you try to pass a number of parameters different then 3, then it will be issued an error.
我认为问题与参数的转换有关,因为 char 不是 32 位。请注意,如果将 char 更改为 int,则效果很好。它与变量的自动提升有关。
比较两者:
gcc
会为第二个发出警告,但不会为第一个发出警告
I think that the problem is related to the casting of the parameters, because char is not 32 bits. Note that if you change the char to int this works fine. It is related to automatic promotion of variables.
Compare the two:
and
gcc gives you warning for the second, but not for the first
在 C 中,空参数列表意味着该函数不带任何参数。我相信您将空参数列表与可变参数混淆了。
更改第一个示例以包含参数将删除警告。
In C an empty parameter list means that the function does not take any parameters. I believe you are confusing an empty parameter list with varargs.
Changing your first example to include the parameters will remove the warning.