简体   繁体   English

链接错误与编译错误

[英]Linking error vs. compilation error

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

Because functions definitions are included in executable at link time but decalration or syntax check all are done at compile time 因为函数定义在链接时包含在可执行文件中,但是在编译时完成了decalration或语法检查

Consider one thing also when you are calling any function and compiler is not able to find the declaration of function then it will generate warning as implicit declaration of func() . 当你调用任何函数并且编译器无法找到函数声明时,请考虑一件事,然后它将生成警告作为implicit declaration of func()

To remove this warning message we provide forward declaration of func, int func(); 要删除此警告消息,我们提供func的前向声明, int func(); and it compiled without any warning message. 它编译时没有任何警告信息。

Do you think why does this happen ? 你觉得为什么会这样吗? It happens because compiler did not find that func() symbol. 这是因为编译器没有找到func()符号。 It's all upto the compiler to make code error free according to the Grammar of the Language. 根据语言语法,编译器完全可以使代码无错误。

But building of final executable is done at link time and then linker started looking for function defition of func() , If found then fine and if not .. then Linker error 但是最终可执行文件的构建是在链接时完成的,然后链接器开始寻找func()函数定义,如果找到那么很好,如果没有..那么Linker error

could not have resolved external symbol _func()

Note: any external symbols are resolved at link time 注意:任何外部符号都在链接时解析

On gcc for only compilation use this : (this may vary according to compiler) 在gcc上只进行编译使用:(根据编译器的不同而不同)

gcc -Werror -c test.c --> It will generate test.o file gcc -Werror -c test.c - >它将生成test.o文件

then try to link it and make executable 然后尝试链接它并生成可执行文件

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

The standard doesn't say when an error should be reported - it's up to the compiler, but basically it's because that's when the errors are caught . 该标准没有说明何时应该报告错误 - 这取决于编译器,但基本上是因为那是在捕获错误时

First, the compiler parses the files. 首先,编译器解析文件。 It's easy to see if a struct or class was defined multiple times in the same translation unit ( only this is an error, between translation units you can have multiple class-type definition ), because it deals with that translation unit. 很容易看出是否在同一个翻译单元中多次定义了一个structclass只有这是一个错误,在翻译单元之间你可以有多个类类型定义 ),因为它处理那个翻译单元。

Second, it links the object files together (linking). 其次,它将目标文件链接在一起(链接)。 Only now can it tell that the same symbol was exported multiple times, because that's when the error occurs per-say. 只有现在它可以告诉多次导出相同的符号,因为那是每次发生错误的时候。

When compiling a program the compiler needs to know which exact definition of a structure to use. 编译程序时,编译器需要知道要使用的结构的确切定义。 But we only need to know which exact function to use only when we are trying to link the program. 但是我们只需要知道在我们尝试链接程序时才使用哪个确切的函数。

So if a structure is defined twice compiler is confused during compilation hence complains at compile time. 因此,如果定义了两次结构,编译器在编译期间会混淆,因此在编译时会抱怨。

For a function during compile time you can have multiple definitions but confusion arises only during linking so it complains during linking. 对于编译期间的函数,您可以有多个定义,但仅在链接期间出现混淆,因此在链接期间会产生抱怨。

What you are saying is not necessarily true. 你说的不一定是真的。

If you "inline" the function definition in a header and then subsequently write its definition in the compilation unit you will get an error 如果在函数头中“内联”函数定义,然后在编译单元中写入其定义,则会出现错误

...already has a definition.

The case you are referring to is when two different compilation units define (or see a definition) of the same function, so there is no compilation error in any individual compilation unit, it is the combination of them that causes the link error. 您指的是两个不同的编译单元定义(或查看定义)相同函数的情况,因此在任何单独的编译单元中都没有编译错误,它们的组合会导致链接错误。

Note incidentally that this is where the keyword inline actually makes a difference. 请注意,这是关键字inline实际上有所作为的地方。 For a non-templated function defined in a header, if you use the inline keyword, it will mean multiple compilation units can exist with this function defined. 对于标头中定义的非模板化函数,如果使用inline关键字,则意味着可以存在多个编译单元,并且定义了此函数。 It does not actually guarantee the compiler will inline it. 它实际上并不保证编译器会内联它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM