【发布时间】:2015-11-01 11:11:06
【问题描述】:
我正在尝试运行添加了-g 标志并删除-O2 标志编译的旧MUD 驱动程序,以便我可以调试它。我有一个带有原型void try_to_swap(void) 的函数,但定义是void try_to_swap(volatile int* interrupted)。在函数内部检查该指针的值:
if(*interrupted)
...
函数调用不带参数,如原型-try_to_swap();
使用优化标志一切正常。但是如果没有它,我在调用函数时会得到一个SIGSEGV。问题是指针指向进程无法访问的地址(0x3b - 每次),因此出现分段错误。
我的问题是:
a) 为什么我在制作过程中没有收到任何错误?编译器不应该以某种方式注意到调用中缺少参数吗?
b) 在优化期间,编译器是否会以某种方式处理指针的值以使程序不会崩溃?
c) 解决这个问题的正确方法是什么?从定义中删除指针,将其添加到原型中?指针仅在此函数中使用,并且仅在提到的if 中使用。它似乎没有在任何地方初始化。或者它可能以某种方式自动初始化?我对volatile 指针不太熟悉。但是指针值是函数调用之前堆栈集中的随机垃圾,因为没有提供参数值。这在 C 中是否合法,默认值不是一个选项?
【问题讨论】:
-
当函数尝试使用您未传递的参数时,您将有未定义的行为。不要这样做!
-
如果您必须调用不带参数的函数,则创建两个函数,一个带参数,另一个不带参数并调用另一个带有一些默认参数的函数。
-
为什么决定在没有参数的情况下调用它对我来说是个谜。也许在以前的一些版本中,一个 volatile int 被用来确定某种中断信号。但是该函数是用
void作为参数声明的。那么为什么当定义与原型不匹配时链接器不抱怨呢? -
在 C 中,函数调用仅在编译时根据声明的原型进行检查,在链接时无法进行检查。只有 C++ 将参数作为函数签名的一部分,而不是 C。
-
感谢您的cmets我找到了here的信息,但我仍然对链接感到困惑。现在它是有道理的,C 没有修改,所以只检查名称。非常感谢您的回答!
标签: c function pointers call volatile