如何知道重载gcc选择了哪个函数

How to know which function overloading gcc selects

本文关键字:函数 选择 何知道 重载 gcc      更新时间:2023-10-16

这是我的上下文:

#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;
}

to_string(y)的调用是一个"错误",因为类型nb::YYY不存在函数to_string。但事实上,这是有效的!

我用编译这个

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

这编译时没有错误,也没有警告。在这个简单的例子中,我知道当GCC为to_string(y)查找名称时,它会找到to_string(priority),但在一个大项目中,要找到GCC选择的函数并不简单。

那么,有没有一种方法可以通过检查.o或将选项传递给GCC来确定GCC选择的"后验"函数?

我在linux上使用GCC 4.7.2。

您可以使用源信息objdump。让我们试试你的例子(为了清楚起见,我将使用gcc 4.9.2:

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

您将看到:

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

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

现在转到调用点,看看实际调用的是什么。

      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

我想,一切都很清楚。