如果我们在C(C99 / C11)和C ++中的函数外部使用预定义变量__func__
会发生什么?
#include <stdio.h>
const char* str = __func__;
int main(void)
{
printf("%s", str);
return 0;
}
gcc 4.7.2仅发出警告(启用-Wall -W -pedantic
)并且不打印任何内容。
标准没有明确说明任何事情:
ISO / IEC 14882:2011
8.4.1一般[dcl.fct.def.general]
8 函数本地预定义变量
__func__
定义为a 形式static const char __func__[] = "function-name";
的定义 已提供,其中function-name是实现定义的 串。未指定此变量是否具有地址 与程序中任何其他对象的不同。
ISO / IEC 9899:2011
6.4.2.2预定义标识符
1 标识符
__func__
应由翻译人员隐式声明,如同,立即 在每个函数定义的开头括号之后, 声明static const char __func__[] = "function-name";
出现了,其中function-name是词法封闭的名称 功能
UB?错误?或其他什么?
答案 0 :(得分:23)
标准没有明确说明任何事情
这意味着未定义的行为。
从C标准(强调我的):
(C99,4.p2)&#34;如果违反了约束之外出现的''shall''或''should not''要求,则行为未定义。未定义的行为在本国际标准中以“未定义行为”或省略任何明确的行为定义来表示。这三者之间的重点没有区别;它们都描述了“未定义的行为”。&#34;
答案 1 :(得分:7)
(根据之前的评论推广)
__func__
位于保留名称空间中,因此允许实现在命名空间范围内用于任何目的,即不需要实现来诊断(错误)使用__func__
函数,因为标准中没有任何内容禁止实现将__func__
定义为char
的命名空间范围数组,如果这是实现者想要做的那样。
它可能是未定义的,或者它可以被定义为字符串,或者其他任何东西,并且该实现仍然符合。
因此,尝试在函数外部使用它是未定义的行为,因为它可能定义也可能不定义,可能是也可能不是正确的类型可用。
对于与符合实现一起使用时问题中的代码如何具有未定义行为的具体示例,我相信实现可以将其定义为nullptr
(因此示例将在printf
中崩溃)或者甚至可以将其定义为扩展为空指针的解除引用的宏,然后在每个函数的入口处#undef
进行定义,并在每个函数之后#define
它(因此示例将在{{1}之前崩溃开始!)