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++20std::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)