【问题标题】:Address of function main() in C/C++C/C++ 中函数 main() 的地址
【发布时间】:2015-04-18 12:35:40
【问题描述】:

有没有办法在 C 或 C++ 中找出 ma​​in() 的地址? 既然它本身就是一个函数,那会不会有它自己的地址呢?

【问题讨论】:

  • main函数被认为是特殊的,因为它有各种限制。其中之一是它的地址不能被取走。 en.cppreference.com/w/cpp/language/main_function 有更多细节。
  • 选择一种语言,C 或 C++。 C 的答案与 C++ 的答案不同。
  • “有没有办法在C/C++中找出main()的地址?” “在C/C++中”这句话通常是没有意义的;询问 C 或 C++。他们大相径庭。
  • 你为什么要问?在哪个操作系统上?用哪个编译器?
  • 您可以让编译器打印出一个 map 文件,该文件将显示所有函数的地址。

标签: c++ c pointers function-pointers


【解决方案1】:

C

当然。简单地去做吧。

#include <stdio.h>

int main(void)
{
   printf("%p\n", &main);
}

C++

不允许使用main 的地址,因此,出于您的目的,没有一个:

[C++11: 3.6.1/3]: 函数 main 不得在程序中使用。 [..]

但是,在 GCC 中,您可以通过编译器扩展采用与 C 中相同的方法:

#include <iostream>

int main()
{
   std::cout << (void*)&main << '\n';
}

您将收到一条不合规的警告。

【讨论】:

  • 这个问题被错误地标记为 C 和 C++。这个答案对于 C++ 是正确的,但对于 C 是不正确的。
  • “因此,出于所有意图和目的,不允许使用 main 的地址” 甚至不能打印出来?
  • 不幸的是,C 中的该示例具有未定义的行为。 %p 采用 void *,而不是 int (*)(void)。没有可移植的方法来打印函数指针,也没有可移植的方法在对象和函数指针之间进行转换。
  • @hvd:有一种方法可以便携打印函数的地址:stackoverflow.com/a/10933437/694576
  • @NominalAnimal 很容易想出一个中断的例子:this example 在更高的 GCC 版本中返回零,但在 GCC 4.5 中返回一个。如果您认为这是一个在更高版本中得到修复的一致性问题,我很乐意阅读它不符合的任何标准,但据我所知,返回 1 在所有版本的 C 和所有版本中都是完全有效的POSIX 的。
【解决方案2】:

我不能 100% 确定问题是来自使用 C/++ 的程序中,还是检索使用 C/C++ 创建的 main() 函数的地址(来自命令行)。

由于您似乎已经收到了关于如何从程序中获取地址的几个很好的答案,我想我想提一下您也可以从 nm 获取此信息。

nm program|grep main

【讨论】:

    【解决方案3】:

    如果在任何系统中找不到 main 的地址.. 调用函数 foo() 作为 main 中的唯一语句,让 main 返回它返回的任何内容,并使用 foo 的地址而不是 main。

    请注意,调用 main 不一定会重新启动您的代码,即使没有静态/全局变量也是如此。编译器在实际调用 main 之前生成启动代码。

    如果您想在调用 main 之前设置断点,请编写如下代码:

    static int i=foo();
    

    并且 foo 将在前面的数据初始化步骤中被调用。

    【讨论】:

      猜你喜欢
      • 2016-04-03
      • 1970-01-01
      • 2020-10-01
      • 2020-12-03
      • 2017-12-22
      • 1970-01-01
      • 2022-06-20
      • 2013-07-25
      • 2014-08-05
      相关资源
      最近更新 更多