Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Linker. How could symbol be defined and undefined simultaneously?

Tags:

c++

linker

$ nm --demangle /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/libsupc++.a  | grep "__cxxabiv1::__class_type_info::~__class_type_info"

gives following output:

0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
0000000000000000 T __cxxabiv1::__class_type_info::~__class_type_info()
                 U __cxxabiv1::__class_type_info::~__class_type_info()
                 U __cxxabiv1::__class_type_info::~__class_type_info()

So, how to interpret this output?

  1. Here is multiple definitions of the symbol (three T's) - how it could be? Why linker produced such library with violated ODR? What is the purpose? And why all of them have the same (and strange) address (0000000000000000)?
  2. How the same symbol could be both defined (T) and undefined (U) simultaneously?
like image 334
Void Avatar asked Sep 11 '15 08:09

Void


1 Answers

A static library (archive file, .a) is essentially a collection of individual .o files (plus some indexing information so the linker can find the .o files it needs). Some of those undefined symbols are in a different object than the one that defines them. If you look at the full output of nm this becomes clear. (Or use the -o flag to nm.)

The reason you have multiple defined symbols is that demangle isn't a 1-to-1 operation. In my copy of libsupc++, those three definitions are:

0000000000000000 T _ZN10__cxxabiv117__class_type_infoD0Ev
0000000000000000 T _ZN10__cxxabiv117__class_type_infoD1Ev
0000000000000000 T _ZN10__cxxabiv117__class_type_infoD2Ev

Why are there several symbols which all demangle to the destructor? They're destructors for different situations. gcc uses the Itanium ABI for C++, whose name mangling rules are described here.

like image 166
Wim Lewis Avatar answered Oct 04 '22 08:10

Wim Lewis