merovingien
merovingien

Reputation: 329

How to know which function overloading gcc selects

This is my context:

#include <string>
#include <map>
#include <sstream>
#include <iostream>

namespace na {
    enum XXX { X1, X2 };

    std::string to_string(XXX x) {
        static const std::map<XXX, std::string> MAP { {X1, "X1"}, {X2, "X2"} };

        return MAP.at(x);
    }
}

namespace nb {
    enum YYY { Y1 = 1001, Y2 = 1002 };
}

typedef char priority;

std::string to_string(priority p) {
    std::ostringstream oss;
    oss << p;
    return oss.str();
}

int main()
{
    na::XXX x = na::X1;

    std::cout << "x: " << to_string(x) << "\n";

    nb::YYY y = nb::Y2;

    std::cout << "y: " << to_string(y) << "\n";

    return 0;
}

The call to to_string(y) is a "mistake" because no function to_string exists for the type nb::YYY. But in fact this works !

I compile this with :

g++ -o main.o -c -std=c++11 -Wall -Wextra -pedantic main.cpp
g++ -o function_overloading main.o

And this compiles with no error, no warning. In that simple case I know that when GCC does the name lookup for to_string(y) it finds to_string(priority) but in a big project, it is not simple to find which function GCC has chosen.

So, is there a way to determine which function GCC chose, "a posteriori", by examining the .o, or by passing an option to GCC ?

I use GCC 4.7.2 on linux.

Upvotes: 2

Views: 124

Answers (1)

Konstantin Vladimirov
Konstantin Vladimirov

Reputation: 7009

You might objdump with source information. Lets try your example (I will use gcc 4.9.2 for clarity:

g++ -c -O0 -gdwarf-2 gccover.cpp -std=c++11
objdump -Sdr gccover.o >& gccover.dis

You will see:

<_ZN2na9to_stringENS_3XXXE>:
std::string to_string(XXX x)

and

<_Z9to_stringc>:
std::string to_string(priority p)

Now just go to point of call and look what is actually called.

      std::cout << "y: " << to_string(y) << "\n";
 296: 8b 45 e8              mov    -0x18(%rbp),%eax
 299: 0f be d0              movsbl %al,%edx
 29c: 48 8d 45 e0           lea    -0x20(%rbp),%rax
 2a0: 89 d6                 mov    %edx,%esi
 2a2: 48 89 c7              mov    %rax,%rdi
 2a5: e8 00 00 00 00        callq  2aa <main+0x76>
      2a6: R_X86_64_PC32  _Z9to_stringc-0x4

I think, everything is clear.

Upvotes: 2

Related Questions