我是否正确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”之类的内容吗?
答案 0 :(得分:14)
"姓名" C ++中的函数?
"实现定义的字符串"为编译器提供了一些灵活性,可以将所有这些信息填充到字符串中。它向程序员发送一条消息,告诉您不应该尝试执行字符串比较或解析,或者实际上除了记录值之外还要执行任何操作(如果您想要可移植性)。
(你甚至不能将这些值相互比较,因为它们并不能保证它们是唯一的。似乎所有重载都可以产生相同的字符串。所以用它来编译剖析器统计数据是不明智的。)
答案 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标准不允许这样做。