Quelle est la différence entre __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
et où sont - ils documentés? Comment puis-je décider lequel utiliser?
la source
Quelle est la différence entre __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
et où sont - ils documentés? Comment puis-je décider lequel utiliser?
__func__
est un identifiant déclaré implicitement qui se développe en une variable de tableau de caractères contenant le nom de la fonction lorsqu'il est utilisé à l'intérieur d'une fonction. Il a été ajouté à C en C99. À partir de C99 §6.4.2.2 / 1:
L'identifiant
__func__
est implicitement déclaré par le traducteur comme si, immédiatement après l'accolade ouvrante de chaque définition de fonction, la déclarationstatic const char __func__[] = "function-name";
est apparu, où nom-fonction est le nom de la fonction entourant lexicalement. Ce nom est le nom sans fioritures de la fonction.
Notez qu'il ne s'agit pas d'une macro et qu'elle n'a aucune signification particulière lors du prétraitement.
__func__
a été ajouté à C ++ dans C ++ 11, où il est spécifié comme contenant "une chaîne définie par l'implémentation" (C ++ 11 §8.4.1 [dcl.fct.def.general] / 8), ce qui n'est pas tout à fait utile comme spécification en C. (La proposition originale à ajouter __func__
au C ++ était N1642 ).
__FUNCTION__
est une extension pré-standard prise en charge par certains compilateurs C (y compris gcc et Visual C ++); en général, vous devez utiliser __func__
là où il est pris en charge et uniquement __FUNCTION__
si vous utilisez un compilateur qui ne le prend pas en charge (par exemple, Visual C ++, qui ne prend pas en charge C99 et ne prend pas encore en charge la totalité de C ++ 0x, ne fournir __func__
).
__PRETTY_FUNCTION__
est une extension gcc qui est essentiellement la même que __FUNCTION__
, sauf que pour les fonctions C ++, elle contient le "joli" nom de la fonction, y compris la signature de la fonction. Visual C ++ a une extension similaire (mais pas tout à fait identique), __FUNCSIG__
.
Pour les macros non standard, vous voudrez consulter la documentation de votre compilateur. Les extensions Visual C ++ sont incluses dans la documentation MSDN des «macros prédéfinies» du compilateur C ++ . Les extensions de la documentation de gcc sont décrites dans la page de documentation de gcc "Noms de fonction en tant que chaînes".
__FUNCTION__
, ils font des choses légèrement différentes. gcc donne l'équivalent de__func__
. VC donne la version non décorée, mais toujours ornée, du nom. Pour une méthode nommée "foo", gcc vous donnera"foo"
, VC vous donnera"my_namespace::my_class::foo"
.__PRETTY_FUNCTION__
il apparaît dans la liste comme étant disponible et lorsque je déplace ma souris dessus, il affiche des informations sur le nom de la fonction, mais il ne parvient pas à compiler.Bien qu'il n'ait pas pleinement répondu à la question initiale, c'est probablement ce que la plupart des gens recherchent sur Google.
Pour GCC:
la source
__func__
marche quand il est intégré dans une autre fonction? Disons que j'ai function1, cela ne prend aucun argument. function1 appelle function2 qui inclut__func__
, quel nom de fonction sera imprimé, 1 ou 2?__func__
c'est une macro, elle se traduira dans la fonction dans laquelle vous vous trouvez actuellement. Si vous la mettez dans f1 et appelez f1 dans f2, vous obtiendrez toujours f1.__PRETTY_FUNCTION__
gère les fonctionnalités C ++: classes, espaces de noms, modèles et surchargemain.cpp
Compiler et exécuter:
Production:
Vous pouvez également être intéressé par les traces de pile avec des noms de fonction: imprimer la pile d'appels en C ou C ++
Testé dans 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 est entré en C ++ 20, nous avons donc encore une autre façon de le faire.
La documentation dit:
où NTBS signifie "Chaîne d'octets terminée Null".
Je vais essayer quand le support arrivera à GCC, GCC 9.1.0
g++-9 -std=c++2a
ne le supporte toujours pas.https://en.cppreference.com/w/cpp/utility/source_location les réclamations seront comme:
Sortie possible:
notez donc comment cela renvoie les informations sur l'appelant et est donc parfait pour une utilisation dans la journalisation, voir aussi: Existe - t-il un moyen d'obtenir le nom de la fonction dans une fonction C ++?
la source
__func__
est documenté dans la norme C ++ 0x à la section 8.4.1. Dans ce cas, il s'agit d'une variable locale de fonction prédéfinie de la forme:où "nom de fonction" est spécifique à l'implémentation. Cela signifie que chaque fois que vous déclarez une fonction, le compilateur ajoute implicitement cette variable à votre fonction. Il en va de même pour
__FUNCTION__
et__PRETTY_FUNCTION__
. Malgré leur majuscule, ce ne sont pas des macros. Bien que__func__
soit un ajout à C ++ 0xcompilera toujours le code en utilisant
__func__
.__PRETTY_FUNCTION__
et__FUNCTION__
sont documentés ici http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names .__FUNCTION__
est juste un autre nom pour__func__
.__PRETTY_FUNCTION__
est le même qu'en__func__
C mais en C ++ il contient également la signature de type.la source
__func__
ne fait pas partie de C ++ 03. Il a été ajouté en C ++ 0x, mais C ++ 0x n'est pas encore "la norme C ++", il est toujours sous forme de brouillon.Pour ceux qui se demandent comment ça se passe en VS.
MSVC 2015 Update 1, cl.exe version 19.00.24215.1:
production:
Utilisation de
__PRETTY_FUNCTION__
déclencheurs d'erreur d'identification non déclarée, comme prévu.la source