C++ 什么';这两个函数的区别是什么?

C++ 什么';这两个函数的区别是什么?,c++,c,compiler-construction,standards,C++,C,Compiler Construction,Standards,\uuu PRETTY\u FUNCTION\uuu、\uu FUNCTION\uuu、\uu func\uuu之间有什么区别,它们在哪里被记录?如何决定使用哪一个?\uuuuu func\uuuu是一个隐式声明的标识符,当在函数内部使用时,它会扩展为包含函数名的字符数组变量。它是在C99中添加到C的。根据§6.4.2.2/1: 标识符\uuuu func\uuuu由转换器隐式声明,就好像在每个函数定义的左括号后面,声明 static const char __func__[] = "

\uuu PRETTY\u FUNCTION\uuu
\uu FUNCTION\uuu
\uu func\uuu
之间有什么区别,它们在哪里被记录?如何决定使用哪一个?

\uuuuu func\uuuu
是一个隐式声明的标识符,当在函数内部使用时,它会扩展为包含函数名的字符数组变量。它是在C99中添加到C的。根据§6.4.2.2/1:

标识符
\uuuu func\uuuu
由转换器隐式声明,就好像在每个函数定义的左括号后面,声明

static const char __func__[] = "function-name";
出现,其中function name是词汇封闭函数的名称。此名称是函数的未加修饰的名称

请注意,它不是宏,在预处理过程中没有特殊意义

在C++ 11中,将< > >函数>函数> /COD>添加到C++中,其中指定为包含“实现DE-EnEd字符串”(C++ 11 11)[4.4.1[DCL .fCT.DEF.GUE]/8 ],这与C.规范中不太有用。
函数是一些C编译器(包括gcc和Visual C++)支持的预标准扩展;一般来说,在使用它的时候,你应该使用<代码>·y'FrimeSux<代码>,只使用<代码>函数>函数>代码>,如果你使用的是不支持它的编译器(例如Visual C++,它不支持C99,还不支持所有的C++ 0x,不提供<代码>
 <代码>函数>函数>代码>是一个GCC扩展,它与AytFiels基本相同,除了C++函数中包含函数的“漂亮”名称,包括函数的签名。VisualC++有类似的(但不完全相同)扩展,

对于非标准宏,您需要查阅编译器的文档。VisualC++扩展包含在C++编译器的MSDN文档中。gcc文档扩展在gcc文档页面中进行了描述,并在C++0x标准第8.4.1节中进行了说明。在这种情况下,它是一个预定义的函数局部变量,形式如下:

static const char __func__[] = "function-name ";
其中“函数名”是具体的实现。这意味着无论何时声明函数,编译器都会将此变量隐式添加到函数中。这同样适用于
\uuuuu函数
\uuu漂亮的函数
。尽管它们的大写字母,但它们不是宏。尽管
\uuuu func\uuuuu
是对C++0x的添加

g++ -std=c++98 ....
仍将使用
\uuuu func\uuuu
编译代码


\uuuu PRETTY\u FUNCTION\uuuu
\uuuu FUNCTION\uuuu
在这里有文档记录<代码>\uuuu函数\uuuu
只是
\uuuuu函数\uuuu
的另一个名称<代码> > PrPyTyByFixy与C中的代码> >函数>函数>代码相同,但在C++中也包含了类型签名。

< P>尽管没有完全回答原始问题,但这大概是Google想要查看的大多数人的。

对于GCC:

$cat test.cpp
#包括
int main(int argc,字符**argv)
{

STD::CUT<强> >代码> PrimTyl函数> /Cuff>处理C++特性:类、命名空间、模板和过载

main.cpp

#include <iostream>

namespace N {
    class C {
        public:
            template <class T>
            static void f(int i) {
                (void)i;
                std::cout << "__func__            " << __func__ << std::endl
                          << "__FUNCTION__        " << __FUNCTION__ << std::endl
                          << "__PRETTY_FUNCTION__ " << __PRETTY_FUNCTION__ << std::endl;
            }
            template <class T>
            static void f(double f) {
                (void)f;
                std::cout << "__PRETTY_FUNCTION__ " << __PRETTY_FUNCTION__ << std::endl;
            }
    };
}

int main() {
    N::C::f<char>(1);
    N::C::f<void>(1.0);
}
输出:

__func__            f
__FUNCTION__        f
__PRETTY_FUNCTION__ static void N::C::f(int) [with T = char]
__PRETTY_FUNCTION__ static void N::C::f(double) [with T = void]
您可能还对具有函数名的堆栈跟踪感兴趣:

在Ubuntu 19.04、GCC 8.3.0中测试

C++20
std::source\u location::function\u name

进入了C++20,所以我们有了另一种方法

文件说:

constexpr const char*函数_name()const noexcept

6返回:如果此对象表示函数体中的位置, 返回实现定义的NTB,该NTB应与 函数名。否则,返回空字符串

其中,NTBS表示“以Null结尾的字节字符串”

当对GCC的支持到达时,我会尝试一下,带有
g++-9-std=c++2a的GCC 9.1.0仍然不支持它

索赔用途如下:

#include <iostream>
#include <string_view>
#include <source_location>
 
void log(std::string_view message,
         const std::source_location& location std::source_location::current()
) {
    std::cout << "info:"
              << location.file_name() << ":"
              << location.line() << ":"
              << location.function_name() << " "
              << message << '\n';
}
 
int main() {
    log("Hello world!");
}

因此,请注意它是如何返回调用方信息的,因此非常适合在日志记录中使用,另请参见:

对于那些想知道它在VS中如何运行的人

MSVC 2015更新1,cl.exe版本19.00.24215.1:

#include <iostream>

template<typename X, typename Y>
struct A
{
  template<typename Z>
  static void f()
  {
    std::cout << "from A::f():" << std::endl
      << __FUNCTION__ << std::endl
      << __func__ << std::endl
      << __FUNCSIG__ << std::endl;
  }
};

void main()
{
  std::cout << "from main():" << std::endl
    << __FUNCTION__ << std::endl
    << __func__ << std::endl
    << __FUNCSIG__ << std::endl << std::endl;

  A<int, float>::f<bool>();
}
#包括
模板
结构A
{
模板
静态空隙f()
{

STD::Cux>代码,函数不是/c++,它是C++ 03的一部分,它已经添加到C++ 0x中,但是C++ 0x还不是C++标准,它仍然是草稿的形式。@ JamesMcNellis现在是这样的,所以请清除注释,删除NoISeCN链接到C99规范(在你的源中有一个浮动链接),什么看起来像是获胜的答案?@legends2k:不,它是C++11中的“实现定义字符串”。这是规范中的实际语言。请参见§8.4.1[dcl.fct.def.general]/8.请注意,虽然gcc和VC都提供了
\uuuuu FUNCTION\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
,但它们所做的事情略有不同。gcc提供了与
\uuuuuuuu FUNCTION\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
相当的名称。VC提供了名称的未修饰但仍有修饰的版本。对于名为
。奇怪的是,我使用的是MSVC 2017 CE,当我键入
\uuu PRETTY\u FUNCTION\uuuu
时,它确实会在列表中显示为可用,当我将鼠标移到它上面时,它确实会显示有关函数名的信息,但它确实无法编译。@FrancisCugler我对此也感到惊讶!同样看到我的问题了吗从clang 3.5开始,好吧,但是
\uuuuu func\uuuuu
嵌入到另一个函数中时是否有效?假设我有function1,它不带参数。function1调用包含
\uuuu func\uuuuuu
的function2,将打印哪个函数名,1或2?@MarcusJ为什么不自己尝试一下呢?
\uu func\uuuuu
是一个宏,它将转换为哦,随便你
info:main.cpp:16:main Hello world!
#include <iostream>

template<typename X, typename Y>
struct A
{
  template<typename Z>
  static void f()
  {
    std::cout << "from A::f():" << std::endl
      << __FUNCTION__ << std::endl
      << __func__ << std::endl
      << __FUNCSIG__ << std::endl;
  }
};

void main()
{
  std::cout << "from main():" << std::endl
    << __FUNCTION__ << std::endl
    << __func__ << std::endl
    << __FUNCSIG__ << std::endl << std::endl;

  A<int, float>::f<bool>();
}
from main(): main main int __cdecl main(void) from A::f(): A<int,float>::f f void __cdecl A<int,float>::f<bool>(void)