【问题标题】:__func__ outside function definition__func__ 外部函数定义
【发布时间】:2021-11-21 14:37:07
【问题描述】:

如果我们在 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__ 被定义为 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?错误?还是别的什么?

【问题讨论】:

  • 我对错误投了赞成票,因为您的引文中使用了“函数局部预定义变量”和“紧跟在每个函数定义的左大括号之后”的措辞。
  • 任何未由标准定义的行为,通过消除,都是未定义的行为;)

标签: c++ c c++11 c99 c11


【解决方案1】:

标准没有明确说明

这意味着未定义的行为。

来自 C 标准(重点是我的):

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

【讨论】:

    【解决方案2】:

    (从之前的评论中提拔)

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

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

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

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

    【讨论】:

    • +1 以获得详尽的解释,而不仅仅是迂腐的引用。
    猜你喜欢
    • 2013-02-24
    • 2013-02-14
    • 1970-01-01
    • 2021-08-20
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多