2
votes

Cpp: Comment comprendre et / ou déboguer des macros complexes?


3 commentaires

Si vous ne l'avez pas déjà fait, consultez github.com/pfultz2/Cloak si vous êtes intéressé par macros de haut niveau. Pour en savoir plus, regardez P99 et BoostPP.


@okovko. Merci pour l'information. C'est ce que j'essaye de comprendre. Voir la réponse de Paul FulTZ II ( stackoverflow.com/questions / 12447557 /…


Vous trouverez votre réponse dans le lien que je vous ai donné. C'est le tutoriel macro de Paul Fultz II sur sa page github: P Oups, voici le lien que je voulais vous donner. C'est l'explication: github.com/pfultz2 / Cape / wiki /…


3 Réponses :


2
votes

Oui, cet outil existe en tant que fonctionnalité de l ' Eclipse IDE . Je pense que le moyen par défaut d'accéder à la fonctionnalité est de survoler une macro que vous souhaitez voir développée (cela affichera l'extension complète), puis d'appuyer sur F2 sur votre clavier (une fenêtre contextuelle apparaît qui vous permet de parcourir chaque extension).

Lorsque j'ai utilisé cet outil pour en savoir plus sur les macros, cela m'a été très utile. Avec juste un peu de pratique, vous n'en aurez plus besoin.

Si quelqu'un ne sait pas comment utiliser cette fonctionnalité, j'ai trouvé un tutoriel sur la documentation Eclipse ici .


10 commentaires

Existe-t-il une telle option avec des blocs de code? Sinon, je vais installer Eclipse.


Je ne connais aucun autre IDE, mais quand je cherchais cette fonctionnalité il y a des années, Eclipse était le seul endroit où je l'ai trouvée.


Cela ne fonctionne que si la macro est correcte. Sinon, vous ne verrez que l'erreur (pas très conviviale et explicative). Vous ne pouvez pas "déboguer" les macros.


Ce n'est tout simplement pas vrai. Il montre toutes les extensions possibles jusqu'à ce qu'une erreur soit atteinte. Pour cette raison, l'outil est extrêmement convivial et explicatif. J'apprécierais que vous supprimiez votre vote négatif, car vos critiques sont mal informées.


@okovko. Génial. J'ai installé Eclipse et cela fonctionne sur un exemple simple comme vous le décrivez. ( #define ABC BCD #define BCD 1 main () {int a = ABC;} ). Merci beaucoup, je valide votre réponse.


Désolé, je viens de lire vos derniers commentaires sur l'erreur en macro. Je me concentrais sur l'installation d'Eclipse. Ils sont très intéressants. Premièrement, je suis très heureux parce que j'ai pu comprendre ce qui se passe avec une expansion complexe comme je l'ai mentionné dans ma question. J'essaierai ce dernier avec erreur, quand je comprendrai ces extensions complexes.


Je ne sais pas pour Eclipse 2019, mais quand je l'ai utilisé il y a des années, j'ai pu développer des macros jusqu'à ce qu'aucune autre extension ne soit possible. Donc, si vous avez une macro complexe avec de nombreuses extensions, et que l'une d'elles est incorrecte, vous pourrez l'étendre jusqu'à ce que vous atteigniez votre erreur, où l'extension se terminera (probablement, en fonction de votre erreur).


Je vais essayer Eclipse Oxygen. Et après, j'installerai d'autres versions et je le testerai. Laissez-moi juste le temps. Mais s'il vous plaît, ne soyez pas si critique l'un envers l'autre avec un vote négatif. Je pourrais vous dire que vous m'aidez tous beaucoup. J'apprécie vos réponses / commentaires car aucun de vous n'a dit de ne pas faire ça, ce n'est pas de bonnes pratiques ... comme cela arrive souvent.


J'ai fait des tests simples et je ne prétends pas être exhaustif. Dans certains cas, je pourrais dire que l'outil eclipse pourrait aider à déboguer certaines erreurs même s'il ne s'agit pas d'un débogueur cpp. Par exemple #define ABC BCD #define BCD EFG #define EFF 1 main () {int a = ABC;} , cela vous informe que le symbole EFG n'a pas pu être résolu et avec F2 trick, vous apprenez que l'expansion n'a que deux étapes qui sont ABC -> BCD -> EFG.


Oui, vous obtiendrez autant d'extensions que possible. Dans les extensions de macros complexes avec conditionnelles, vous pouvez par exemple développer la condition incorrecte et vous pourrez voir que l'erreur s'est produite lorsque vous développez vers la macro incorrecte. Il continuera à s'étendre au-delà de l'endroit où l'erreur s'est produite, mais vous pouvez déterminer où se trouve l'erreur en parcourant les extensions.



0
votes

La seule façon de voir ce qui ne va pas avec votre macro est d'ajouter l'option qui conservera les fichiers temporaires une fois la compilation terminée. Pour gcc, c'est l'option -save-temps . Vous pouvez ouvrir le fichier .i et les macros développées.

Les indexeurs IDE (comme Eclipse) n'aideront pas trop. Ils ne développeront pas (comme les autres réponses l'indiquent) les macros jusqu'à ce que l'erreur se produise. entrez la description de l'image ici


9 commentaires

Mais je n'ai pas toutes les étapes comme avec F2 dans l'IDE Eclipse. C'est ce que je vois quand j'utilise l'option -E, n'est-ce pas?


C'est Mais vous n'avez aucune étape si la macro est erratique. Le visualiseur Eclipse est uniquement capable (car il utilise l'indexeur interne) de voir les macros correctes .


Vous devriez essayer de répondre à la question pour améliorer votre réponse.


@okovko vous ne devriez pas publier les fausses réponses. Veuillez me montrer toute macro erratique partiellement développée dans la vue macro (F2) dans l'éclipse.


Et s'il y a des erreurs, avec le -save-temps, que se passe-t-il? Est-il possible de voir, dans la sortie (fichier .i), les premières étapes d'expansion jusqu'à ce qu'une erreur se produise?


Non, vous aurez l'effet du travail du préprocesseur. Il n'y a aucun moyen de «déboguer» le préprocesseur - vous pouvez écrire le vôtre.


@P__J__ eh bien, nous parlons de votre réponse en ce moment. La question est de "voir le résultat étape par étape" donc c'est vous qui publiez une "fausse réponse", puisque vous n'offrez aucune solution. Quoi qu'il en soit, j'ai trouvé un tutoriel sur la façon d'utiliser cette fonctionnalité d'éclipse. Ici . Je pense que vous êtes juste confus.


@okovko essaie de changer cette macro en pour donner une erreur puis continue la discussion. Le débogage est nécessaire lorsque quelque chose ne fonctionne pas


@P__J__ passez votre souris sur la fenêtre contextuelle jaune et appuyez sur F2. Vous devriez avoir une nouvelle fenêtre contextuelle avec des flèches pour aller et venir. Si vous ne le voyez pas, alors peut-être avez-vous raison sur le fait qu'Eclipse permettra uniquement de parcourir les extensions de macro qui ne sont pas mal formées. Tout comme un débogueur ne vous permettra pas de parcourir du code qui ne se compile pas. Si vous avez plutôt fait une erreur de logique dans vos macros, plutôt qu'une erreur de compilation, vous pouvez parcourir vos macros.



1
votes

Cette réponse à une autre question est pertinente.

Lorsque vous faites des tours de préprocesseur étranges (qui sont légitimes), cela est utile pour demander au compilateur de générer le formulaire prétraité (par exemple avec gcc -C -E si vous utilisez GCC ) et examinez ce formulaire prétraité.

En pratique, pour un fichier source foo.c , il est (parfois) judicieux d'obtenir sa forme prétraitée foo.i avec gcc -C -E foo.c> foo.i et regardez dans ce foo.i .

Parfois, il est même logique d'obtenir ce foo.i sans information de ligne. L'astuce ici (supprimer les informations de ligne contenues dans les lignes commençant par # ) serait de faire:

gcc -C -E foo.c | grep -v '^#' > foo.i

Ensuite, vous pouvez indenter foo. i et compilez-le, par exemple avec gcc -Wall -c foo.i ; vous obtiendrez des emplacements d'erreur dans le fichier prétraité et vous pourrez comprendre comment vous l'avez obtenu et revenir à vos macros de préprocesseur (ou à leurs invocations).

N'oubliez pas que Le préprocesseur C est principalement une transformation textuelle fonctionnant au niveau du fichier. Il n'est pas possible de macro-développer quelques lignes isolément (car les lignes précédentes peuvent avoir joué avec #if combiné avec #define -peut-être dans les #include -d fichiers - ou options de préprocesseur telles que -DNDEBUG transmises à gcc ou g ++ ). Sous Linux, consultez également feature_test_macros (7)

Un exemple connu d'expansion qui fonctionne différemment lorsqu'il est compilé avec ou sans -DNDEBUG transmis au compilateur est assert . La signification de assert (i ++> 0) (une chose très mauvaise à coder) en dépend et illustre que la macro-expansion ne peut pas être faite localement (et vous pourriez imaginer un en-tête antérieur ayant # définir NDEBUG 1 même si bien sûr il est de mauvais goût).

Un autre exemple (très courant en fait) où l'expansion de macro dépend du contexte est toute macro utilisant __LINE__ ou __COUNTER__ ...

NB. Vous n'avez pas besoin d'Eclipse pour tout cela, juste un assez bon éditeur de code source (ma préférence est emacs mais c'est une question de goût): pour la tâche de prétraitement, vous pouvez utiliser votre compilateur.


6 commentaires

Il semble que la question demande spécifiquement une expansion macro étape par étape, et la question mentionne également l'option -E. Existe-t-il un outil en ligne de commande pour développer une macro étape par étape? Ce serait bien d'en trouver un.


Eh bien, c'est vraiment possible, je ne pense pas que quiconque l'ait encore fait. Par exemple, il est implémenté dans Eclipse IDE (voir ma réponse). Eclipse vous permet de voir chaque extension étape par étape, au lieu du résultat final, comme vous le faites avec l'indicateur -E.


Eh bien, cela fonctionne dans le cas général. En fait, dans les commentaires sur mes réponses, la personne qui a posé la question a confirmé que cela fonctionne, même lorsqu'il y a une erreur.


Continuons cette discussion dans le chat .


Question de débutant sur Eclipse IDE: Eclipse utilise-t-il certaines options de cpp pour capturer ces étapes intermédiaires ou y a-t-il une "réécriture" de cpp dans Eclipse? Dans le second cas, comment pourrions-nous être sûrs qu'il donnera le même résultat que cpp?


Le préprocesseur C est défini par le standard C, donc tout ce qu'Eclipse fait suit le standard. Malheureusement, le standard C ne définit pas le comportement du préprocesseur, il existe donc des différences d'implémentation entre les différents compilateurs. Heureusement, ces différences sont rares et généralement les principaux fournisseurs de compilateurs normalisent les différences au fil du temps (vous ne verrez pas beaucoup de différences entre gcc et clang).