C /符号中的const数组在带有nm的已编译* .o文件中不可见

时间:2013-10-30 11:11:37

标签: c embedded nm

我正在为嵌入式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变量?

1 个答案:

答案 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