链接错误与编译错误

时间:2012-11-14 09:52:59

标签: c++ c compiler-construction linker

为什么结构的双重声明会导致编译错误,而函数的双重定义会导致链接错误

4 个答案:

答案 0 :(得分:4)

因为函数定义在链接时包含在可执行文件中,但是在编译时完成了decalration或语法检查

当你调用任何函数并且编译器无法找到函数声明时,请考虑一件事,然后它将生成警告implicit declaration of func()

要删除此警告消息,我们提供func的前向声明int func();,并且编译时没有任何警告消息。

你认为为什么会这样吗?这是因为编译器没有找到func()符号。根据语言语法,编译器完全可以使代码无错误。

但最终可执行文件的构建是在链接时完成的,然后链接器开始寻找func()的函数定义,如果找到则很好,如果没有..那么Linker error

could not have resolved external symbol _func()

注意:在链接时解析任何外部符号

在gcc上只进行编译使用:(根据编译器的不同而不同)

gcc -Werror -c test.c - >它将生成test.o文件

然后尝试链接它并制作可执行文件

gcc -Werror -o test test.o - > test是可执行的

答案 1 :(得分:2)

标准没有说明何时应该报告错误 - 这取决于编译器,但基本上是因为是在捕获错误时

首先,编译器解析文件。很容易看出structclass是否在同一翻译单元中多次定义(只有这是一个错误,翻译单位之间可以有多个类型定义),因为它涉及翻译单位。

其次,它将目标文件链接在一起(链接)。只有现在它可以告诉多次导出相同的符号,因为那是每次发生错误的时候。

答案 2 :(得分:2)

编译程序时,编译器需要知道要使用的结构的确切定义。但是我们只需要知道在我们尝试链接程序时才使用哪个确切的函数。

因此,如果定义了两次结构,编译器在编译期间会混淆,因此在编译时会抱怨。

对于编译期间的函数,您可以有多个定义,但仅在链接期间出现混淆,因此在链接期间会产生抱怨。

答案 3 :(得分:1)

你所说的不一定是真的。

如果您在标题中“内联”函数定义,然后在编译单元中编写其定义,则会出现错误

  

...already has a definition.

您所指的情况是两个不同的编译单元定义(或查看定义)相同的函数,因此在任何单个编译单元中都没有编译错误,它们的组合会导致链接错误

请注意,这是关键字inline实际上有所作为的地方。对于标头中定义的非模板化函数,如果使用inline关键字,则意味着可以存在多个编译单元,并定义此函数。它实际上并不能保证编译器会内联它。