我正在为嵌入式power-pc平台编程(使用wind-river diab编译器,如果这很重要)并且想要将我的代码与预编译的目标文件* .o(为同一平台编译,课程)。其中一个目标文件需要一个外部符号,我必须自己定义并链接到* .o文件 - 否则链接器会抱怨:
Undefined symbol 'mySymbolName' in file 'precompiled.o'
但是,即使我使用缺少的符号编译源文件(预编译的o。*文件所需的签名相同:'unsigned char const [16]')&链接它与precompiled.o链接仍然抱怨。 myCFile.c:
unsigned char const mySymbolName[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
我使用以下命令编译代码:
bin/dplus -g -Xdebug-dwarf3 -W:c++:.c -Xc++-abr -Xmake-dependency=0xd -Xsmall-data=0 -Xsmall-const=0 -Xlint=0x40 -O -tPPC5554FF:cross -I{some include pathes...} -DTOOL_FAMILY=diab -DTOOL=diab -DPowerPC -DPPC5500 -o "myObjectFile.o" -c "myCFile.c"
编译器警告我,mySymbolName已声明但从未使用过(当然不是 - 它是从另一个目标文件中引用的 - 因此我认为警告很好)。链接命令:
bin/dld -tPPC5554FF:cross file.dld -o "output.elf" myObjectFile.o precompiled.o
因错误而失败:
Undefined symbol 'mySymbolName' in file 'precompiled.o'
使用nm(当然是针对特定目标平台)我发现,我的符号在我编译的目标文件中不可见:nm只是没有显示任何内容。但是,我找到了一种以nm为单位显示符号的方法。如果我在我的c文件中删除'const'说明符,请:
unsigned char mySymbolName[16] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
nm正确显示mySymbolName。
所以我的问题是:这怎么可能?这是预期的行为 - 还是在不同的平台上表现不同?是否允许ANSI-C编译器优化在编译时删除未引用的const变量?
答案 0 :(得分:4)
您的Diab编译器调用似乎强制进行C ++编译,C ++中const
的语义与数字中C的语义不同。
在C ++中,文件范围内的const
具有隐式静态(或内部)链接,因此不会放在目标文件的符号表中。这与C的行为不同,所以如果你使用C编译,它会产生你所期望的。
添加显式extern
声明(或使用C编译):
extern unsigned char const mySymbolName[16] ;
有关详细信息,请参阅前一段时间的Ben Voigt answer to a question on const
semantics I asked。