Question

I'm programming for an embedded power-pc platform (using the wind-river diab compiler, if that matters) and want to link my code with pre-compiled object files *.o (compiled for the same platform, of course). One of these object files needs an external symbol, that I have to define myself and link against that *.o file - otherwise the linker would complain:

Undefined symbol 'mySymbolName' in file 'precompiled.o'

However, even if I compile a source file with that missing symbol (same signature that the precompiled o.* file expects: 'unsigned char const [16]') & link it against the precompiled.o, the linker still complains. myCFile.c:

unsigned char const mySymbolName[16] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

I compile the code with the command:

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"

The compiler warns me, that mySymbolName is declared but never used (of course it's not - it's referenced from another object file - so the warning is fine in my opinion). Linking with the command:

bin/dld   -tPPC5554FF:cross file.dld -o "output.elf"  myObjectFile.o precompiled.o

Fails with the error:

Undefined symbol 'mySymbolName' in file 'precompiled.o'

Using nm (of course for the specific target platform) I figured out, that my symbol is not visible in my compiled object file: nm just doesn't show anything. However, I found a way to Show my symbol in nm. If I drop the 'const' specifier in my c file, to:

unsigned char mySymbolName[16] = {
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ,0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

nm shows mySymbolName correctly.

So my question is: How is that possible? Is this expected behaviour - or does it behave differently on different platforms? Is it a allowed optimization for ANSI-C Compiler to remove unreferenced const-variables at compile-time?

Was it helpful?

Solution

Your Diab compiler invocation appears to be forcing C++ compilation, the semantics of const in C++ differ from those of C in a number if ways.

In C++ a const at file scope has implicit static (or internal) linkage, so will not be placed in the object file's symbol table. This differs from the behaviour of C, so had you used C compilation, it would have produced what you expected.

Add an explicit extern declaration (or use C compilation):

extern unsigned char const mySymbolName[16] ;

For more information see Ben Voigt answer to a question on const semantics I asked a while ago.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top