C使用未定义的符号进行编译

时间:2013-02-22 00:16:09

标签: c

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

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

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

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

2 个答案:

答案 0 :(得分:1)

如果没有可用的声明,则编译器使用函数的默认声明来获取未知数量的参数并返回int。如果你打开编译器警告(例如-Wall -Wextra -Werror和gcc,请查看编译器的文档),你应该得到一个编译时警告。

答案 1 :(得分:1)

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

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

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