1

我使用的是旧版本的 Diab C 编译器。

在我的代码中,我取了一个函数名并将其重新定义为具有相同签名的函数指针。在进行此更改之前,代码有效。更改后,它导致嵌入式系统锁定。

函数指针在头文件中声明为 extern,在一个 .c 文件中定义,并在另一个 .c 文件中使用。当从第二个 .c 文件调用它时,它会导致系统锁定。当我尝试使用 sprintf 添加调试信息时,它最终告诉我这是一个未定义的符号。我意识到头文件未包含在第二个 .c 文件中。当我#included 时,所有内容都已编译并正常工作。

我的问题是,即使符号在调用位置未定义,是否有一些 C 规则允许编译器推断函数签名?据我了解,在我进行任何更改之前很久就应该出现错误。

4

2 回答 2

1

如果没有可用的声明,则编译器使用函数的默认声明,该函数采用未知数量的参数并返回一个 int。如果您出现编译器警告(例如-Wall -Wextra -Werror,使用 gcc,请检查编译器的文档),您应该会收到编译时警告。

于 2013-02-22T00:18:39.520 回答
1

最有可能的是,该代码最初可以工作,因为它是在 C89 或类似模式下编译的。1989 年的 C 标准允许在不首先声明函数的情况下调用函数。

当您更改代码以使用指针但不包含指针的声明时,编译器会假定您的指针实际上是一个函数并生成调用指针的代码,就好像指针内部有可执行代码一样。结果,程序停止工作是可以理解的。

您应该做的是启用所有可能的警告(对于 gcc: -Wall-Wextra并确保启用优化(-O2很好),因为它启用代码分析),特别是对于调用没有原型的函数。更好的做法可能是将编译器切换到 C99 模式(-std=c99在 gcc 中)或切换到 C99 编译器。1999 年的 C 标准禁止调用没有原型的函数,并带有一些 C89 中没有的有用特性。

于 2013-02-22T00:33:05.663 回答