我对gcc链接器的兼容检查行为有疑问,看起来它不会检查声明和定义的兼容性。
例如,我在文件 ac 中定义了uint32_t
变量eTest
,然后在文件 bc中使用uint8_t
类型声明它如下所示,由于声明中eTest
的类型被更改,因此假设存在警告。但是,不会弹出任何警告消息。
看起来像声明中的变量类型的语句是不必要的,因为虽然声明没有类型语句的变量,但这些也没有警告。
交流转换器
uint32_t eTest = 0;
b.c
extern uint8_t eTest;
答案 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.c
和b.c
都应该包含(在其开头附近)#include "myheader.h"
,并且myheader.h
头文件应该包含extern uint8_t eTest;
。
请注意,-flto
{G}内部的lto1
&amp; cc1
编译器用于&#34;编译&#34;时间和#34;链接&#34;时间。真正的binutils ld
或gold
链接器(由gcc
运行)不知道类型。 ELF符号(几乎)没有类型(实际上数据和功能仍然是分开的。)