我正在为嵌入式 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 编译器在编译时删除未引用的常量变量是否允许优化?