C/symbol中的常量数组在编译的带nm的*.o文件中不可见

C/symbol中的常量数组在编译的带nm的*.o文件中不可见,c,embedded,nm,C,Embedded,Nm,我正在为一个嵌入式power pc平台编程(如果需要的话,使用wind river diab编译器),并希望将我的代码与预编译的对象文件*.o(当然是为同一平台编译的)链接起来。其中一个对象文件需要一个外部符号,我必须定义自己并链接到该*.o文件-否则链接器会抱怨: Undefined symbol 'mySymbolName' in file 'precompiled.o' 但是,即使我编译了一个缺少符号的源文件(与预编译的o.*文件期望的签名相同:“unsigned char const[

我正在为一个嵌入式power pc平台编程(如果需要的话,使用wind river diab编译器),并希望将我的代码与预编译的对象文件*.o(当然是为同一平台编译的)链接起来。其中一个对象文件需要一个外部符号,我必须定义自己并链接到该*.o文件-否则链接器会抱怨:

Undefined symbol 'mySymbolName' in file 'precompiled.o'
但是,即使我编译了一个缺少符号的源文件(与预编译的o.*文件期望的签名相同:“unsigned char const[16]”),并将其与预编译的.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"
bin/dld   -tPPC5554FF:cross file.dld -o "output.elf"  myObjectFile.o precompiled.o
编译器警告我,mySymbolName是声明的,但从未使用过(当然不是-它是从另一个对象文件引用的-所以我认为这个警告很好)。与命令链接:

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"
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变量?

贵公司编译器调用似乎强制C++编译,C++中的代码> > const < /> >语义不同。 <>在文件范围内C++有一个隐式静态(或内部)链接,因此不会放在对象文件的符号表中。这与C的行为不同,因此如果您使用C编译,它将产生您所期望的结果

添加显式的
extern
声明(或使用C编译):


有关更多信息,请参阅前一段时间。

是否尝试向
myCFile.c
添加额外的外部声明<代码>外部无符号字符常量mySymbolName[16]Diab数据编译器在优化方面做了非常繁重的工作。我建议删除所有优化,并看到问题仍然存在(使用
const
限定符),如果这让它重新出现,那么您已经限定了问题的范围,并且可以确定由哪个优化器标志负责。(如果不是,你可以忽略我的评论:)@SergeyL。fileA.c中的
extern
关键字对放入fileB.c编译对象的内容没有影响。。。如果fileA.c需要它,那么没有它源代码将无法编译。。。相反,将C代码编译为C代码。没有那种C++废话!(不管怎么说,对于纯C来说……这表明编译器有一个正确的、真正的C前置,对吗?@H2CO3:当然,我是在你添加评论时键入这一建议的。也就是说,有可能有理由使用C++编译,即使对于代码也可以编译为C,但是必须接受结果代码是C++而不是C,并且存在一些细微的语义差异。然而,在这种情况下,这似乎可能是一个错误;你会以为君士坦丁会提到这件事,如果这是故意的,当然。关于故意编译的观点是正确的,尽管我仍然不喜欢这种方法(有些东西告诉我,如果需要的话,那么某些地方就坏了,不一定是程序员的错,但仍然如此。)无论如何,谢谢你添加了这句话,+1.因为添加了<代码> ExtNe/COD>会使它在C和C++中语义上相同,所以我建议无论如何都要这样做。但是为了声明一个兴趣,我开发C++中的嵌入式系统作为首选项,所以我将挥动那个特定的标志。是的,你是对的!标志'W:C++:.c'使编译器强制C++编译,这就是为什么符号不在对象文件符号表中的原因。删除此标志后,它对我有效-只需添加“extern”(而不是删除标志)也有效。非常感谢。