__func__ C和C ++之间的值差异

时间:2013-01-04 20:08:26

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

我是否正确C标准保证_ _ func _ _ value始终是封闭函数的名称,而在C ++中(我的意思是C ++ 11),它可以是任何实现定义的字符串(例如,如果我们有没有参数的函数foo,我们可以得到像“Some string fdgdg asdfs fsdf sd”这样的东西?)

ISO / IEC 9899:2011

6.4.2.2预定义标识符

  

语义

     

1标识符_ _ func _ _应由。隐式声明   翻译好像,紧跟着每个人的开口支撑   函数定义,声明static const char _ func _ [] =   “函数名”;出现了,其中 function-name是该名称   词汇封闭功能

ISO / IEC 14882:2011

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

  

8函数本地预定义变量_ _ func _ _被定义为a   static const char _ _ func _ _ [] =“function-name   “;已提供, function-name是一个实现定义的   串即可。未指定此变量是否具有地址   与程序中任何其他对象的不同。

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

3 个答案:

答案 0 :(得分:14)

"姓名" C ++中的函数?

  • 是否符合其命名空间?
  • 是否按参数类型命名了重载函数?
  • 返回类型怎么样,不用于重载?
  • 功能模板会发生什么?
  • 调用约定是名称的一部分吗?
  • 应该' const'和'易变的'是在类型名称之前还是之后写的?

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

(你甚至不能将这些值相互比较,因为它们并不能保证它们是唯一的。似乎所有重载都可以产生相同的字符串。所以用它来编译剖析器统计数据是不明智的。)

答案 1 :(得分:4)

我怀疑这是为了允许C ++编译器使用__func__中的错位名称。

答案 2 :(得分: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标准不允许这样做。