【问题标题】:Is it illegal to take address of main() function?获取 main() 函数的地址是否违法?
【发布时间】:2013-03-09 16:03:54
【问题描述】:

根据this answer 使用函数 main() 是非法的(第 3.6.1.3 节),如果函数的名称出现在可能计算的表达式中,则使用函数( §3.2)。

假设我有这个代码:

printf( "%p", &main );

函数名称main()出现在表达式&main中。

上面的代码会不会是非法的?

【问题讨论】:

  • §3.2 定义了“odr-used”,而不是“used”。我认为这里“使用”的含义更为笼统——你不能以任何方式使用main
  • 好问题。出于好奇——你为什么需要这个?或者问你的问题是基于相同的,我问的是我的:)
  • @sftrabbit C++03 清楚地说:“如果对象或非重载函数的名称出现在潜在求值的表达式中,则使用它。” C++11 没有说明“使用”是什么意思;我的猜测是引入“odr-used”是为了解决其他一些问题,没有人解决对main的限制。
  • @JamesKanze 啊,我在看 C++11。
  • 另见this question关于打印函数指针。

标签: c++ function main


【解决方案1】:

是的。正如你所引用的,标准说你不能使用 main

还要注意,函数的地址匹配"%p"。 对应的参数必须的类型为void*;任何其他 类型(可能char* 除外)是非法的,并导致未定义 行为。

【讨论】:

  • 那么我需要对函数地址进行强制转换来代替%p吗?
  • @sharptooth 除了没有从指针到函数到void*的转换。 (我认为 C++11 将此作为可选功能,但在早期版本中,它需要诊断。)
【解决方案2】:

由于main 未被“使用”(您没有对其进行评估),因此根据您提供的链接,它应该是合法的。

【讨论】:

  • 取一个函数的地址就是在使用它。
【解决方案3】:

通常不使用指向main() 的指针或main() 的地址,但是..

无论如何,这是允许的,因为每个函数(以及任何符号,例如变量)都有自己的地址。并且可能需要 main() 的地址 - 特别是当您为嵌入式系统编写代码并使用动态加载代码或运行时检查时。或者有一个引导加载程序和实际运行的固件。

main() 通常是动态加载代码的入口点(例如从 FLASH 到 RAM),因此它在引导加载程序中被引用(直接调用或分配给相关指针)。

参考MicroC-OS/II或VxWorks——都用main()这种方式

【讨论】:

  • 不幸的是......这完全超出了标准。该实现允许使用它可以收集的所有黑魔法、平台特定代码、编译器特定代码;但这并没有说明程序对另一个平台/编译器的可移植性
  • 我认为嵌入式系统中的救命稻草是 main() 可以用完全自定义的东西代替。因此,由于 C++ 标准滞后,所有嵌入式 C++ 实现都需要将其 main 重命名为其他名称。我建议所有嵌入式系统都使用another_wg21_fiasco()而不是main()来解决这个问题。或者......他们可以简单地继续使用 C 语言进行编程,因为 C 语言的标准不那么落后。
猜你喜欢
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多