请使用以下代码:
int main()
{
decltype(main()) x = 0;
return x;
}
gcc抱怨:
main.cpp: In function 'int main()':
main.cpp:8:19: warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
decltype(main()) x = 0;
^
main.cpp:8:19: warning: ISO C++ forbids taking address of function '::main' [-Wpedantic]
但没有铿锵。那么decltype(main())
会引发这个错误呢? decltype
如何获取main的地址?
答案 0 :(得分:11)
在这种情况下,GCC的诊断可能没有正确措辞,因为decltype
不需要知道main
的地址;它只需要知道它的类型。但是,警告基于标准(§3.6.1/ 3)中的以下内容:
函数
main
不得在程序中使用。
我认为GCC将此解释为意味着您甚至无法在未评估的表达中使用它。
Clang(版本3.4无论如何)似乎根本没有实现这个规则,即使我打开了我能想到的所有标志,即使main
递归调用自己。这就是为什么它不会给你一个警告。
答案 1 :(得分:10)
这个主题最近实际上出现在帖子undefined behaviour study group discussion list的What does "The function main shall not be used within a program" mean?中。它没有马上出现,但是here是它在线程中开始的地方,带有以下语句:
我不认为decltype(main())是一种使用,或者 的sizeof(decltype(主))。
一组非常简短的回复如下:
是的,我只是看不出那会是什么用途。你可能意味着 sizeof(decltype(& main))在后一种情况下。
我认为最常见的非ODR使用主要是在之后定义它 一个前瞻性声明,现在Steven Clamage已经澄清了这一点 应该是不正确的。 “使用”作为一种更广泛的定义 没有引用ODR的名称查找结果现在看起来正确。
和
C ++ 98提及'使用'有一个交叉引用3.2 [basic.def.odr]。 C ++ 11不再具有交叉引用,并且未更改为说 ' odr-use',所以我希望它意味着任何使用。
所以似乎对3.6.1
主要功能的解释似乎是:
函数main不得在程序中使用。 [...]
表示任何即使在未评估的上下文中也是如此,因此gcc
在这里产生错误是正确的,尽管消息本身似乎没有意义。
更新
注意original proposal: N3154修复Defect report 1109会将3.6.1
更改为:
函数main不应在程序中使用odr-used(3.2)。 ......
这将允许decltype
示例,但在accepted时进行了修改,我们可以看到新proposal: N3214已更改为我们今天所拥有的内容:
函数main不得在程序中使用
这将强烈表明UB邮件列表中任何使用main
格式错误的观点确实是正确的。