【问题标题】:Calling function without parameters when the definition includes parameters当定义包含参数时调用不带参数的函数
【发布时间】: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


【解决方案1】:

a) 在 C 中,() 表示“任何参数”,与没有参数的 (void) 不同。 try_to_swap() 有效,但对用户来说不是一个好的文档。

b) 是的,编译器似乎检测到缺少的参数,只是传递了一个空指针。

c) 您可以将指针参数添加到原型并传递内部if 所需的内容或尝试trick

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 2020-07-29
    • 2013-02-17
    相关资源
    最近更新 更多