답변:
__func__
함수 내에서 사용될 때 함수 이름을 포함하는 문자 배열 변수로 확장되는 암시 적으로 선언 된 식별자입니다. C99에서 C에 추가되었습니다. 에서 C99 / 1 §6.4.2.2 :
식별자
__func__
는 마치 각 함수 정의의 여는 중괄호 바로 뒤에 선언처럼 마치 번역자에 의해 암시 적으로 선언됩니다.static const char __func__[] = "function-name";
여기서 function-name은 어휘 포함 함수의 이름입니다. 이 이름은 기능의 이름이 지정되지 않은 이름입니다.
매크로가 아니며 전처리 과정에서 특별한 의미가 없습니다.
__func__
C ++ 11의 C ++에 추가되었으며, "구현 정의 문자열"(C ++ 11 §8.4.1 [dcl.fct.def.general] / 8)을 포함하는 것으로 지정되었습니다. C의 스펙으로 유용합니다 ( __func__
C ++에 추가 할 원래 제안 은 N1642였습니다 ).
__FUNCTION__
일부 C 컴파일러가 지원하는 사전 표준 확장입니다 (gcc 및 Visual C ++ 포함). 일반적으로 __func__
지원되는 위치 를 사용해야 하며 지원 __FUNCTION__
하지 않는 컴파일러를 사용하는 경우 에만 사용해야 합니다 (예 : C99를 지원하지 않고 C ++ 0x를 모두 지원하지 않는 Visual C ++는 지원하지 않습니다) 제공 __func__
).
__PRETTY_FUNCTION__
는 __FUNCTION__
C ++ 함수의 경우 함수의 서명을 포함하여 함수의 "예쁜"이름을 포함한다는 점을 제외하고 는 대부분과 동일한 gcc 확장입니다 . Visual C ++의 확장명은 비슷하지만 동일하지는 않습니다 __FUNCSIG__
.
비표준 매크로의 경우 컴파일러 설명서를 참조하십시오. Visual C ++ 확장은 C ++ 컴파일러의 "사전 정의 된 매크로" 의 MSDN 설명서에 포함되어 있습니다. gcc 설명서 확장은 gcc 설명서 페이지 "함수 이름 문자열"에 설명되어 있습니다.
__FUNCTION__
하지만 약간 다른 작업을 수행합니다. gcc는에 해당 __func__
합니다. VC는 장식되지는 않았지만 여전히 꾸며진 버전의 이름을 제공합니다. "foo"라는 메소드의 경우 gcc가 "foo"
VC를 제공 "my_namespace::my_class::foo"
합니다.
__PRETTY_FUNCTION__
할 때 목록에 사용 가능한 것으로 표시되고 마우스를 움직일 때 함수 이름에 대한 정보를 표시하지만 컴파일하지는 않습니다.
원래 질문에 완전히 대답하지는 않았지만 이것은 아마도 대부분의 사람들이 인터넷 검색을 원했던 것일 것입니다.
GCC의 경우 :
petanb@debian:~$ cat test.cpp
#include <iostream>
int main(int argc, char **argv)
{
std::cout << __func__ << std::endl
<< __FUNCTION__ << std::endl
<< __PRETTY_FUNCTION__ << std::endl;
}
petanb@debian:~$ g++ test.cpp
petanb@debian:~$
petanb@debian:~$ ./a.out
main
main
int main(int, char**)
__func__
다른 기능에 포함되어 있으면 작동합니까? function1이 있다고 가정하면 인수가 필요하지 않습니다. function1은를 포함하는 function2를 호출하며 __func__
, 어떤 함수 이름이 인쇄됩니까, 1 또는 2?
__func__
매크로는 현재 사용중인 모든 함수로 변환됩니다. f1에 넣고 f2에서 f1을 호출하면 항상 f1을 얻게됩니다.
__PRETTY_FUNCTION__
C ++ 기능 처리 : 클래스, 네임 스페이스, 템플릿 및 오버로드
main.cpp
#include <iostream>
namespace N {
class C {
public:
template <class T>
static void f(int i) {
(void)i;
std::cout << __func__ << std::endl
<< __FUNCTION__ << std::endl
<< __PRETTY_FUNCTION__ << std::endl;
}
template <class T>
static void f(double f) {
(void)f;
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
}
int main() {
N::C::f<char>(1);
N::C::f<void>(1.0);
}
컴파일하고 실행하십시오.
g++ -ggdb3 -O0 -std=c++11 -Wall -Wextra -pedantic -o main.out main.cpp
./main.out
산출:
f
f
static void N::C::f(int) [with T = char]
static void N::C::f(double) [with T = void]
함수 이름을 가진 스택 추적에 관심이있을 수도 있습니다. C 또는 C ++의 인쇄 호출 스택
우분투 19.04, GCC 8.3.0에서 테스트되었습니다.
C ++ 20 std::source_location::function_name
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf C ++ 20에 들어갔으므로 아직 다른 방법이 있습니다.
설명서는 다음과 같이 말합니다.
constexpr const char * function_name () const noexcept;
6 반환 :이 객체가 함수 본문의 위치를 나타내는 경우 함수 이름에 해당하는 구현 정의 NTBS를 반환합니다. 그렇지 않으면 빈 문자열을 반환합니다.
여기서 NTBS는 "Null Terminated Byte String"을 의미합니다.
지원이 GCC에 도착하면 GCC 9.1.0에서 g++-9 -std=c++2a
지원하지 않을 때 시도해 보겠습니다 .
https://en.cppreference.com/w/cpp/utility/source_location 클레임 사용법은 다음과 같습니다.
#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!");
}
가능한 출력 :
info:main.cpp:16:main Hello world!
따라서 이것이 호출자 정보를 리턴하는 방법을 기록하므로 로깅에 사용하기에 적합합니다. 또한 C ++ 함수 내에 함수 이름을 가져 오는 방법이 있습니까?
__func__
섹션 8.4.1의 C ++ 0x 표준에 설명되어 있습니다. 이 경우 다음과 같은 형식의 사전 정의 된 함수 로컬 변수입니다.
static const char __func__[] = "function-name ";
여기서 "함수 이름"은 구현 사양입니다. 즉, 함수를 선언 할 때마다 컴파일러가이 변수를 함수에 암시 적으로 추가합니다. 동일은 사실이다 __FUNCTION__
하고 __PRETTY_FUNCTION__
. 그들의 대소 문자에도 불구하고, 그들은 매크로가 아닙니다. __func__
C ++ 0x에 추가 되었지만
g++ -std=c++98 ....
여전히을 사용하여 코드를 컴파일합니다 __func__
.
__PRETTY_FUNCTION__
그리고 __FUNCTION__
여기에 설명되어 있습니다 http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names . __FUNCTION__
에 대한 또 다른 이름입니다 __func__
. C __PRETTY_FUNCTION__
와 동일 __func__
하지만 C ++에는 형식 서명도 포함되어 있습니다.
__func__
C ++ 03의 일부가 아닙니다. C ++ 0x에 추가되었지만 C ++ 0x는 아직 "C ++ 표준"이 아니며 아직 초안 형식입니다.
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>();
}
산출:
main ()에서 : 본관 본관 int __cdecl main (void) A :: f ()에서 : A <int, float> :: f 에프 void __cdecl A <int, float> :: f <bool> (void)
__PRETTY_FUNCTION__
예상대로 트리거 선언되지 않은 식별자 오류를 사용 합니다.