GCC链接器会检查声明和定义的兼容性吗?

时间:2017-06-02 09:34:24

标签: c gcc

我对gcc链接器的兼容检查行为有疑问,看起来它不会检查声明和定义的兼容性。

例如,我在文件 ac 中定义了uint32_t变量eTest,然后在文件 bc中使用uint8_t类型声明它如下所示,由于声明中eTest的类型被更改,因此假设存在警告。但是,不会弹出任何警告消息。 看起来像声明中的变量类型的语句是不必要的,因为虽然声明没有类型语句的变量,但这些也没有警告。

交流转换器

uint32_t eTest = 0;

b.c

extern uint8_t eTest;

1 个答案:

答案 0 :(得分:0)

  

例如,我在文件a.c中定义了一个uint32_t变量eTest,然后在文件b.c中用uint8_t类型声明它,如下所示,它假设有一个警告,因为在声明中更改了eTest的类型。

这是特定于实施的。 BTW,在Linux上使用最新的GCC编译器与 链接时间优化 一起使用(所以实际编译所有.c文件和链接< / em>包含gcc -flto -O2的目标文件,例如make CC='gcc -flto -O2'进行诊断。

但是,-flto会减慢编译时间(几乎加倍)。

Ad Kerrek SB在his deleted answer中告诉我,不需要检测到这种违规行为,具体来说,您的程序有一些undefined behavior。对于C11,请检查n1570(我瞥了一眼,没有发现任何明确的要求来检测您的情况)。

实际上,extern uint8_t eTest;声明应该放在一些常见的标题文件myheader.h中,您应该#include在所有源文件中(尤其是a.c),然后您将得到一个错误(即使没有-flto)。所以,即使你纠正了类型,你所做的编码也很差。您需要在一些公共头文件中集中共享声明。阅读有关C preprocessor的更多信息。因此,a.cb.c都应该包含(在其开头附近)#include "myheader.h",并且myheader.h头文件应该包含extern uint8_t eTest;

请注意,-flto {G}内部的lto1&amp; cc1编译器用于&#34;编译&#34;时间和#34;链接&#34;时间。真正的binutils ldgold链接器(由gcc运行)不知道类型。 ELF符号(几乎)没有类型(实际上数据和功能仍然是分开的。)