22

如果我们__func__在 C (C99 / C11) 和 C++ 中的函数之外使用预定义变量会发生什么?

#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__被定义为好像static const char __func__[] = "function-name"; 已经提供了表单的定义,其中函数名称是实现定义的字符串。未指定此类变量是否具有与程序中任何其他对象不同的地址。

ISO/IEC 9899:2011

6.4.2.2 预定义标识符

1标识符__func__应由翻译器隐式声明,就好像紧跟在每个函数定义的左大括号之后static const char __func__[] = "function-name"; 出现声明一样,其中 function-name 是词法封闭函数的名称。

UB?错误?或者是其他东西?

4

2 回答 2

24

标准没有明确说明

这意味着未定义的行为。

来自 C 标准(强调我的):

(C99, 4.p2) “如果违反了出现在约束之外的‘应该’或‘不应’要求,则行为未定义。未定义的行为在本国际标准中以“ '未定义的行为''或省略任何明确的行为定义。这三者之间在强调方面没有区别;它们都描述了“未定义的行为”。

于 2013-01-02T14:03:06.710 回答
7

(从之前的评论中提升)

__func__位于保留的命名空间中,因此允许实现在命名空间范围内出于任何目的使用它,即不需要实现来诊断__func__函数外部的(错误)使用,因为标准中没有任何内容禁止实现定义__func__为一个命名空间范围的数组,char如果这就是实现者想要做的。

它可能是未定义的,或者它可能被定义为一个字符串,或者其他任何东西,并且该实现仍然符合要求。

因此,尝试在函数之外使用它是未定义的行为,因为它可能已定义或未定义,并且可能或可能不是可用的正确类型。

对于问题中的代码在与符合标准的实现一起使用时如何具有未定义行为的具体示例,我相信实现可以将其定义为nullptr(因此示例会崩溃printf),甚至可以将其定义为扩展为取消引用的宏一个空指针,然后#undef它在每个函数的入口处和#define它在每个函数之后(所以这个例子会在main开始之前崩溃!)

于 2013-01-02T14:30:17.837 回答