C++, name mangling and function signatures

One of the guys in the office was having problems compiling POVray on solaris - the last link step kept failing with an unknown symbol. It turns out that the POVray source had declared the symbol in the .h file using the pattern:
int function(const char \*, unsigned int);
but defined the function in the .cpp file using the pattern:
int function(const char \*, const unsigned int) {}
When it came to the link step, the compiler complained that other object files referencing the function could not link, because the function as declared was not in any of the linked object files. We can easily ascertain this fact using the nm utility. To more easily see the differences, you need to use the -C option, which performs the neat-oh C++ name demangling.
The example code is here. Which demonstrates this issue precisely.
First we compile, but do not link the .cpp files. To perform this step do: CC -c \*.cpp.
% nm -C \*.o


inter.o:

[Index]   Value      Size    Type  Bind  Other Shndx   Name

[2]     |         0|      25|FUNC |GLOB |0    |2      |int function(const char\*,const unsigned)
                                                       [__1cIfunction6FpkckI_i_]
[1]     |         0|       0|FILE |LOCL |0    |ABS    |inter.cpp


link.o:

[Index]   Value      Size    Type  Bind  Other Shndx   Name

[4]     |         0|       0|NOTY |GLOB |0    |ABS    |__fsr_init_value
[2]     |         0|       0|FUNC |GLOB |0    |UNDEF  |int function(const char\*,unsigned)
                                                       [__1cIfunction6FpkcI_i_]
[1]     |         0|       0|FILE |LOCL |0    |ABS    |link.cpp
[3]     |         0|      41|FUNC |GLOB |0    |2      |main
without the demangling, you would see the function names in brackets, which are not easy to distinguish, but once you add in the demangling the difference is obvious. Of course even if you #included the .h file into the .cpp file to 'type enforce' the function signature, because to the compiler they are not the same function it simply presumes that the declaration in the .h file is for another function.
It is annoying, but you have to pay attention to these things when you're writing C++.
Contrast the patterns observed when we compile using the gnu compiler: g++ -c \*.cpp
% nm -C \*.o


inter.o:

[Index]   Value      Size    Type  Bind  Other Shndx   Name

[2]     |         0|       0|SECT |LOCL |0    |1      |
[3]     |         0|       0|SECT |LOCL |0    |2      |
[5]     |         0|       0|SECT |LOCL |0    |4      |
[4]     |         0|       0|SECT |LOCL |0    |3      |
[6]     |         0|      10|FUNC |GLOB |0    |1      |function(const char\*, unsigned)
                                                       [_Z8functionPKcj]
[1]     |         0|       0|FILE |LOCL |0    |ABS    |inter.cpp


link.o:

[Index]   Value      Size    Type  Bind  Other Shndx   Name

[5]     |         0|       0|SECT |LOCL |0    |5      |
[2]     |         0|       0|SECT |LOCL |0    |1      |
[3]     |         0|       0|SECT |LOCL |0    |3      |
[4]     |         0|       0|SECT |LOCL |0    |4      |
[6]     |         0|       0|SECT |LOCL |0    |7      |
[9]     |         0|       0|NOTY |GLOB |0    |UNDEF  |__gxx_personality_v0
[8]     |         0|       0|NOTY |GLOB |0    |UNDEF  |function(const char\*, unsigned)
                                                       [_Z8functionPKcj]
[1]     |         0|       0|FILE |LOCL |0    |ABS    |link.cpp
[7]     |         0|      53|FUNC |GLOB |0    |1      |main
Who is correct at this step? I don't quite have the answer for that, as if you tried to define two functions that differed by that const, the compiler has no way to disambiguate them. If you're being really picky, you could say that dropping the const against standard pass-by-value variables is incorrect; after all it's a function taking a const, and it's declaration should respect that.
Comments:

Post a Comment:
Comments are closed for this entry.
About

petesh

Search

Archives
« April 2014
MonTueWedThuFriSatSun
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
    
       
Today