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

__func__ value difference between C and C++

本文关键字:func c++ 之间      更新时间:2023-10-16

C标准保证_ _ function _ _ value始终是封闭函数的名称,而在c++(当然,我指的是c++ 11)中,它可以是任何实现定义的字符串(例如,如果我们有函数foo没有参数,我们可以得到类似"Some string fdgdg asdfs fsdf sd"的东西),这真的是正确的吗?

ISO/IEC 9899:2011

6.4.2.2预定义标识符

语义

1标识符_ _函数_ _应由翻译好像,紧跟着每一个开始的大括号函数定义时,声明static const char _ func _ [] ="函数名";,其中function-name是对象的名称lexically-enclosing函数 .

ISO/IEC 14882:2011

8.4.1 general [dcl.fct.def.general]

8函数局部预定义变量_ _ func_ _被定义为定义形式static const char _ _ func _ _ [] = "function-name ";,其中函数名称是实现定义的字符串。没有说明这样的变量是否有地址与程序中任何其他对象不同。

这是什么原因呢?如果我们不能接收当前函数名,返回类似"未知"的东西?

c++中函数的"name"是什么?

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

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

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

我怀疑这是为了允许c++编译器在__func__中使用修改过的名称。

因为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 "answers"funca"的程序,但是标准允许它打印"a:: a"answers"a::funca ",这是C标准不允许的。