I've got a source file that defines a move constructor for a very large class. I compile it with g++ 4.9.2, on a linux system. When I dump the symbol table of the resulting ELF object file, I see 2 listings for the move constructor. Both listings have the same address, the same size, the same type, and the linker links it just fine, with no ODR violations. When I disassemble the object file, I only see one move constructor function. My conclusion is that the symbol table has two entries that point to the same location.
This same behavior also happens for the constructor of this particular class, which is defined in this same source file.
The only compile flag I see that I don't fully understand is '-m64', but I don't know how this would affect the symbol table.
I tried this with g++ 9.2.0 as well, and now I have 3 entries in the symbol table! Two of which point to the same address, and the third points to address 0x0, is in the .text.unlikely section, and is marked as [clone .cold].
Why is this?
edit: I can reproduce this at home with a very small class, actually.
// class.h
class VeryLargeClass
{
int data;
public:
VeryLargeClass(VeryLargeClass&&);
};
// class.cpp
#include "class.h"
VeryLargeClass::VeryLargeClass(VeryLargeClass&& other)
{
data = other.data;
other.data = 0;
}
If I compile this with g++ -c -O3 class.cpp -o class.o, and then dump the symbol table with objdump -t class.o | c++filt I get the following:
class.o: file format elf64-x86-64
SYMBOL TABLE:
0000000000000000 l df *ABS* 0000000000000000 main.cc
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 l d .data 0000000000000000 .data
0000000000000000 l d .bss 0000000000000000 .bss
0000000000000000 l d .note.GNU-stack 0000000000000000 .note.GNU-stack
0000000000000000 l d .eh_frame 0000000000000000 .eh_frame
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 g F .text 000000000000000b VeryLargeClass::VeryLargeClass(VeryLargeClass&&)
0000000000000000 g F .text 000000000000000b VeryLargeClass::VeryLargeClass(VeryLargeClass&&)
Notice how the move constructor shows up twice in the symbol table? I'm guessing I just don't understand something about the ELF format. This was done using g++ 10.2.