6
votes

Macro pour obtenir le nom de la fonction et les valeurs de paramètre de la fonction dans la fonction

Je travaille sur un programme de débogage / journalisation et je vous demandais s'il serait possible de créer une macro que je peux coller à l'intérieur de chaque fonction et imprimera le nom de la fonction et les valeurs de paramètre chaque fois que la fonction est appelée. Le nom de la fonction peut être détourné lors de la compilation, le problème consiste à déterminer comment imprimer des valeurs de paramètre?

Mise à jour: Je me souviens de lire un article pour obtenir des paramètres mais que cela a invoqué le code de montage et le fonctionnement des pointeurs de pile, qui n'est pas compatible avec la plate-forme croisée - quelque chose dont j'ai besoin.


3 commentaires

C ou C ++? Différentes langues.


Mais les macros devraient être les mêmes pour les deux, j'ai sélectionné à la fois d'élargir le public.


Écrivez un laissez-passer LLVM (plugin compilateur) pour instrument vos fonctions.


6 Réponses :


2
votes

Vous pouvez utiliser la fonction __ __ ou __ func __ macro pour le nom de la fonction. Pour les paramètres, je ne pense pas qu'il y ait une macro intégrée pour y parvenir.

Autres macros utiles sont __ ligne __ et __ fichier __

Modifier:

__ Fonction __ et __ FUNC __ ne faisant pas partie de la norme, mais ils sont largement pris en charge.

16.8 traite des macros prédéfinies: xxx

et macros définis par la mise en oeuvre: xxx


7 commentaires

__ func __ est une partie de la norme, mais ce n'est pas une macro. C'est peut-être la raison pour laquelle vous ne l'avez pas trouvé à cet endroit.


@Jensgustedt Nous parlons de la norme C ++?


Non, je parlais de C. en C11, il est 6.4.2.2, un identifiant prédéfini, pas une macro. Afair c'était déjà en C99, il devrait également être en C ++.


@Jensgustedt Ce n'est pas en C ++. Je ne sais pas si C ++ 11 l'a, mais avant cela, non.


Le questionneur a déclaré qu'ils savaient déjà comment obtenir le nom de la fonction d'une macro - la question indiquée était de savoir comment utiliser une macro pour récupérer NA Imprimer les paramètres de fonction.


@Perry je sais, et à cela, j'ai répondu pour les paramètres, je ne pense pas qu'il y ait une macro intégrée pour y parvenir. Et il n'y a pas, comme prouvé dans la dernière partie de la réponse, Lorsque je répertorie toutes les macros prédéfinies de la norme C ++. BTW, comment va votre réponse à ma question?


Hey @jensgustedt Votre P99 offre-t-elle une macro réelle qui ferait cela? J'essaie de créer une version UTF8 de __ func __ , et je ne suis pas tout à fait sûr de savoir comment faire le nom de fonctions actuel-actuel plus directement que d'utiliser __ func __ : / Je reçois beaucoup d'avertissements inutiles à ce sujet et je ne veux pas les désactiver, je souhaite juste que ce soit un peu plus intelligent.



1
votes

Pour le nom de la fonction, vous pouvez utiliser l'identifiant standard (depuis C99) __ func __ .

en C ++, l'identifiant d'extension GNU __ joli_function __ imprimera également les types de paramètres.


1 commentaires

Le questionneur a déclaré qu'il savait comment obtenir le nom de la fonction d'une macro - sa préoccupation imprimait les paramètres de fonction.



0
votes

Il n'y a pas de moyen portable pour obtenir toutes les valeurs de paramètre et les imprimer - vous ne pouvez certainement pas le faire à partir d'une macro. Vous devrez peut-être utiliser une autre méthode pour atteindre ce que vous voulez.


4 commentaires

Quelle est l'autre méthode? Je pourrais certainement utiliser une macro pour substituer C code C.


Vous pouvez faire quelque chose de moche dans lequel vous avez fait toutes vos déclarations de fonction à l'aide d'une macro qui a blaché le code de la déclaration de fonction puis imprimait leurs valeurs à la tête de la fonction elle-même. Ce n'est pas jolie - je ne vais pas descendre ce chemin. De cette façon mène la folie. Dans le monde réel, utilisez simplement GDB ou imprimez ce dont vous avez besoin lorsque vous en avez besoin.


@Perry Comment allez-vous faire ça? +1 De moi si vous pouvez fournir un exemple de travail.


Ce serait vraiment grotesque. La façon dont vous vous contacteriez, il serait d'abuser de l'installation de macro varadic et d'une macro multiligne. Je suis sûr que ça va bien (ce que signifie traiter correctement avec les types de sorties) va être une chienne si elle peut être faite avec une généralité du tout - cela vaut plus qu'un +1, ce serait un Contribution potentielle au concours de programmation C Obfusqué C. (Les hacks similaires que j'ai vus dans le passé, par exemple pour un interprète LISP en C, cela pourrait dépendre de tous les paramètres étant un type.)



0
votes

Voici quelques exemples et astuces avec le débogage avec des macroses. Listes de ms spécifique et < Un href = "http://gcc.gnu.org/onlinedocs/cpp/macros.html#macros" rel = "Nofollow Noreferrer"> GNU 'S


0 commentaires

0
votes

Vous pouvez utiliser un Macro Variagin , puis transmettez le format de la chaîne et les paramètres de fonction à ce. La macro ne sera pas exactement la même pour chaque fonction (car chaque fonction peut avoir des paramètres différents), mais la plupart des travaux réside dans la copie-coller les paramètres qui sont une ligne ci-dessus.

Si votre signature de fonction est la suivante: xxx

Votre macro sera quelque chose comme: xxx

la pièce après le profil_func (__File__, __line __, ... sera variable. Regardez dans le lien sur la façon de faire exactement cela.

Si personne ne suget plus mieux dans sept ans, ce doit être la voie à suivre. Si vous le pouvez Trouvez comment __Pretty_function__ obtient les types de paramètres, vous pourrez peut-être automatiser cela plus loin.

edit

Ce lien est utile. Il décrit trois manières de faire passer la backtrage de Votre demande au moment de l'exécution:

  1. gcc Macro __builtin_return_address
  2. glibc backtrace et backtrace_symbols
  3. libunwind

0 commentaires

0
votes

Le système de macro C ne peut pas référer implicitement les paramètres. Vous devriez les transmettre.

Comme une petite victoire, les macros peuvent compter leurs arguments, il serait donc trace (foo, bar) au lieu de Trace2, Trace3, etc. Ce n'est pas nettement pire que de la trace () au début de la fonction.

Impression réelle des valeurs irait bien. Opérateur de surcharge << ou la main le roulette avec _generic, selon la langue.

Faire ce genre de chose proprement, par ex. Pour déduire les paramètres, une impression basculante sur et désactive de manière dynamique, est accessible via des générateurs de code. Deux styles de ce: 1 / Analysez les commentaires C, ou spécifiques. Voir Swig, Doxygen. 2 / Générer les fonctions de journalisation et le C de quelque chose d'autre

Analyse Le C semble être plus courant. Peut-être parce que vous pouvez facilement l'ajouter au code existant. Générer à partir d'une autre entrée est plus facile à faire de manière fiable. Nom de la fonction, liste des paramètres, chaîne contenant la mise en œuvre, comme fonctionne XML / JSON. Au-delà de la modélisation, j'aime les scripts Python et Lua qui génèrent C et Metadata. Voir aussi la table de la LLVM.


0 commentaires