Was ist der Unterschied zwischen __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
und wo sind sie dokumentiert? Wie entscheide ich mich für eine?
quelle
Was ist der Unterschied zwischen __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
und wo sind sie dokumentiert? Wie entscheide ich mich für eine?
__func__
ist ein implizit deklarierter Bezeichner, der zu einer Zeichenarrayvariablen erweitert wird, die den Funktionsnamen enthält, wenn er innerhalb einer Funktion verwendet wird. Es wurde in C99 zu C hinzugefügt. Ab C99 §6.4.2.2 / 1:
Der Bezeichner
__func__
wird vom Übersetzer implizit deklariert, als ob unmittelbar nach der öffnenden Klammer jeder Funktionsdefinition die Deklarationstatic const char __func__[] = "function-name";
erschien, wobei Funktionsname der Name der lexikalisch einschließenden Funktion ist. Dieser Name ist der schmucklose Name der Funktion.
Beachten Sie, dass es sich nicht um ein Makro handelt und dass es während der Vorverarbeitung keine besondere Bedeutung hat.
__func__
wurde zu C ++ in C ++ 11 hinzugefügt, wo angegeben wird, dass es "eine implementierungsdefinierte Zeichenfolge" enthält (C ++ 11 §8.4.1 [dcl.fct.def.general] / 8), was nicht ganz so ist nützlich als Spezifikation in C. (Der ursprüngliche Vorschlag __func__
, C ++ hinzuzufügen , war N1642 ).
__FUNCTION__
ist eine vorstandardisierte Erweiterung, die einige C-Compiler unterstützen (einschließlich gcc und Visual C ++); im Allgemeinen sollten Sie verwenden__func__
wo es unterstützt wird, und nur verwenden, __FUNCTION__
wenn Sie einen Compiler verwenden, der es nicht unterstützt (z. B. Visual C ++, das C99 nicht unterstützt und noch nicht alles von C ++ 0x unterstützt, nicht zur Verfügung stellen __func__
).
__PRETTY_FUNCTION__
ist eine gcc-Erweiterung, die größtenteils dieselbe ist wie __FUNCTION__
, außer dass sie für C ++ - Funktionen den "hübschen" Namen der Funktion einschließlich der Signatur der Funktion enthält. Visual C ++ hat eine ähnliche (aber nicht ganz identische) Erweiterung __FUNCSIG__
.
Informationen zu nicht standardmäßigen Makros finden Sie in der Dokumentation Ihres Compilers. Die Visual C ++ - Erweiterungen sind in der MSDN-Dokumentation der "Vordefinierten Makros" des C ++ - Compilers enthalten . Die gcc-Dokumentationserweiterungen werden auf der gcc-Dokumentationsseite "Funktionsnamen als Zeichenfolgen" beschrieben.
__FUNCTION__
zwar etwas bieten , jedoch leicht unterschiedliche Aufgaben ausführen . gcc ergibt das Äquivalent von__func__
. VC gibt die nicht dekorierte, aber immer noch geschmückte Version des Namens an. Für eine Methode namens "foo" gibt gcc Ihnen"foo"
, VC gibt"my_namespace::my_class::foo"
.__PRETTY_FUNCTION__
es in der Liste als verfügbar angezeigt. Wenn ich mit der Maus darüber fahre , werden Informationen zum Funktionsnamen angezeigt, die jedoch nicht kompiliert werden können.Obwohl die ursprüngliche Frage nicht vollständig beantwortet wurde, ist dies wahrscheinlich das, was die meisten Leute, die googeln, sehen wollten.
Für GCC:
quelle
__func__
, wenn es in eine andere Funktion eingebettet ist? Nehmen wir an, ich habe Funktion1, es werden keine Argumente benötigt. Funktion1 ruft Funktion2 auf, die enthält__func__
, welcher Funktionsname wird gedruckt, 1 oder 2?__func__
ist ein Makro, es wird in jede Funktion übersetzt, in der Sie sich gerade befinden. Wenn Sie es in f1 setzen und f1 in f2 aufrufen, erhalten Sie immer f1.__PRETTY_FUNCTION__
behandelt C ++ - Funktionen: Klassen, Namespaces, Vorlagen und Überladungmain.cpp
Kompilieren und ausführen:
Ausgabe:
Möglicherweise interessieren Sie sich auch für Stack-Traces mit Funktionsnamen: print call stack in C oder C ++
Getestet in Ubuntu 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 wurde in C ++ 20 integriert, sodass wir noch eine andere Möglichkeit haben.
Die Dokumentation sagt:
Dabei bedeutet NTBS "Null Terminated Byte String".
Ich werde es versuchen, wenn der Support bei GCC eintrifft. GCC 9.1.0
g++-9 -std=c++2a
unterstützt ihn immer noch nicht.https://en.cppreference.com/w/cpp/utility/source_location Die Nutzung von Ansprüchen lautet wie folgt:
Mögliche Ausgabe:
Beachten Sie daher, wie dies die Anruferinformationen zurückgibt und sich daher perfekt für die Protokollierung eignet. Siehe auch: Gibt es eine Möglichkeit, den Funktionsnamen in einer C ++ - Funktion abzurufen?
quelle
__func__
ist im C ++ 0x-Standard in Abschnitt 8.4.1 dokumentiert. In diesem Fall handelt es sich um eine vordefinierte lokale Funktionsvariable des Formulars:Dabei ist "Funktionsname" implementierungsspezifisch. Dies bedeutet, dass der Compiler diese Variable implizit zu Ihrer Funktion hinzufügt, wenn Sie eine Funktion deklarieren. Gleiches gilt für
__FUNCTION__
und__PRETTY_FUNCTION__
. Trotz ihrer Großbuchstaben sind sie keine Makros. Obwohl__func__
ist eine Ergänzung zu C ++ 0xkompiliert weiterhin Code mit
__func__
.__PRETTY_FUNCTION__
und__FUNCTION__
sind hier dokumentiert http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names .__FUNCTION__
ist nur ein anderer Name für__func__
.__PRETTY_FUNCTION__
ist dasselbe wie__func__
in C, enthält jedoch in C ++ auch die Typensignatur.quelle
__func__
ist nicht Teil von C ++ 03. Es wurde in C ++ 0x hinzugefügt, aber C ++ 0x ist noch nicht "der C ++ - Standard", es liegt noch in Entwurfsform vor.Für diejenigen, die sich fragen, wie es in VS geht.
MSVC 2015 Update 1, cl.exe Version 19.00.24215.1:
Ausgabe:
Die Verwendung von
__PRETTY_FUNCTION__
Triggern führt erwartungsgemäß zu einem nicht deklarierten Bezeichnerfehler.quelle