8

我真的正确吗,C 标准保证 _ func _ _ value 始终是封闭函数的名称,而在 C++(我的意思是 C++11,当然)它可以是任何实现定义的字符串(例如,如果我们有没有参数的函数 foo,我们可以得到类似“一些字符串 fdgdg asdfs fsdf sd”)?

ISO/IEC 9899:2011

6.4.2.2 预定义标识符

语义

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

ISO/IEC 14882:2011

8.4.1 一般 [dcl.fct.def.general]

8 函数局部预定义变量 _ _ func _ 被定义为形式的定义 static const char _ _ func _ _ [] = "function-name"; 已提供,其中function-name 是实现定义的 string。未指定此类变量是否具有与程序中任何其他对象不同的地址。

这是什么原因?如果我们无法接收当前函数名,返回类似“未知”的内容?

4

3 回答 3

14

C++ 中函数的“名称”是什么?

  • 它是否由其命名空间限定?
  • 重载函数是否按其参数类型命名?
  • 不用于重载的返回类型呢?
  • 函数模板中会发生什么?
  • 调用约定是名称的一部分吗?
  • 'const' 和 'volatile' 应该写在类型名称之前还是之后?

“实现定义的字符串”在如何将所有这些信息填充到字符串中时为编译器提供了一些灵活性。它会向您(程序员)发送一条消息,如果您想要可移植性,您不应该尝试执行字符串比较或解析,或者实际上除了记录值之外的任何事情。

(您甚至不能将这些值相互比较,因为不能保证它们是唯一的。似乎所有重载都可能产生相同的字符串。因此不建议使用它来编译探查器统计信息。)

于 2013-01-04T20:14:12.250 回答
4

我怀疑这是为了允许 C++ 编译器在__func__.

于 2013-01-04T20:14:28.577 回答
3

因为 C++ 允许基于函数参数的类型重载函数,并且因为函数可以放置在非全局范围内(这两者在标准 C 中都是不允许的),所以词法封闭函数的简单名称是不够的来识别它。

例如,考虑:

class A {
public:
    A() {
        std::cout << __func__ << std::endl;
    }
    void funca() {
        std::cout << __func__ << std::endl;
    }
};

int main() {
    A a;
    a.funca();
}

它应该打印什么?

GCC 将生成一个打印“A”和“funca”的程序,但标准允许它打印“A::A”和“a::funca”,这是 C 标准不允许的。

于 2013-01-04T20:18:35.963 回答