web-dev-qa-db-fra.com

Voir les macros C étendues

Si je veux développer une macro C, quels sont les bons moyens de le faire (en plus du suivi manuel)?

Par exemple, GTK_WIDGET_SET_FLAGS, il utilise une macro qui utilise une macro qui utilise une macro (ou deux) ...

Je veux simplement le voir s’étendre automagiquement d’une manière ou d’une autre, au lieu de rechercher chaque macro, chaque étape du processus.

METTRE À JOUR

J'ai essayé cpp, mais il semblait ne faire que le premier passage

sur:

GTK_WIDGET_SET_FLAGS(obj, 13)

J'ai développé le fichier include, puis:

G_STMT_START{ ((GTK_OBJECT_FLAGS (obj)) |= (13)); }G_STMT_END

Cela s’explique par le message d’erreur que j’obtiens ceci sur stderr (lors de l’utilisation du nom de fichier -o)

 gtk/gtkwidget.h: 34: 21: gdk/gdk.h: Aucun fichier ou répertoire de ce type 
 gtk/gtkwidget.h: 35: 31: gtk/gtkaccelgroup.h: Aucun fichier ou répertoire de ce type 
gtk/gtkwidget.h: 36: 27: gtk/gtkobject.h: Aucun fichier ou répertoire de ce type 
 gtk/gtkwidget.h: 37: 31: gtk/gtkadjustment.h: Aucun fichier ou répertoire de ce type 
 gtk /gtkwidget.h:38:26: gtk/gtkstyle.h: Aucun fichier ou répertoire de ce type 
 gtk/gtkwidget.h: 39: 29: gtk/gtksettings.h: Aucun fichier ou répertoire de ce type 
 gtk/gtkwidget .h: 40: 21: atk/atk.h: Aucun fichier ni répertoire de ce type 

les répertoires gtk, atk et gdk se trouvent tous dans le répertoire de travail actuel. Comment puis-je laisser cpp y effectuer des recherches?

btw, gcc -E donne exactement le même résultat que cpp

Update2:

Le problème du chemin d'inclusion est résolu en utilisant gcc -E et en passant le répertoire d'inclusion avec l'option -I

43
hasen

Selon le compilateur que vous utilisez, il devrait y avoir un moyen de voir le code après que le préprocesseur (qui effectue le développement des macros, les macros ne sont pas du tout connus du compilateur).

Avec gcc, l'option est -E . Voici un exemple simplifié, utilisant du code jouet et non la macro GTK + proprement dite:

~/tmp> cat cpptest.c
#define SET_FLAGS(w, f) ((w)->flags |= (f))

int main(void)
{
        SET_FLAGS(0, 4711);

        return 0;
}
~/tmp> gcc -E cpptest.c
# 1 "cpptest.c"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "cpptest.c"


int main(void)
{
 ((0)->flags |= (4711));

 return 0;
}
57
unwind

Dans Visual Studio, vous pouvez générer le fichier d'unité de traduction résultant du préprocesseur. Vous pouvez aller aux options de projet, C/C++/Preprocessor et mettre "Générer un fichier prétraité" ou "Prétraiter dans un fichier" sur Oui (ou utiliser le commutateur/P ou/EP du compilateur pour inclure des numéros de ligne ou non).

11
Cătălin Pitiș

Vous pouvez vider le développement d'une macro au moment de l'exécution comme ceci:

#include <stdio.h>

/*
 * generic helper macros
 */
#define CALL(macro, arguments) macro arguments
#define STR(...) STR_(__VA_ARGS__)
#define STR_(...) # __VA_ARGS__

/*
 * dumps a macro and its expansion to stdout
 * the second argument is optional and specifies the number of
 * arguments that macro takes: 0 means macro takes zero arguments
 * no second argument means macro is not function-like
 */
#define DUMP_MACRO(macro, ...) \
    do { \
        puts ( \
            "'" \
            # macro STR(DUMP_MACRO_ARGS_ ## __VA_ARGS__) \
            "' expands to '" \
            STR(CALL(macro, DUMP_MACRO_ARGS_ ## __VA_ARGS__)) \
            "'" \
        ); \
    } while (0)
/* helpers for DUMP_MACRO, add more if required */
#define DUMP_MACRO_ARGS_
#define DUMP_MACRO_ARGS_0 ()
#define DUMP_MACRO_ARGS_1 (<1>)
#define DUMP_MACRO_ARGS_2 (<1>, <2>)
#define DUMP_MACRO_ARGS_3 (<1>, <2>, <3>)

/*
 * macros to be used in examples for DUMP_MACRO
 */
#define EXAMPLE ( EXAMPLE0() << 9 )
#define EXAMPLE0() __GNUC__
#define EXAMPLE1(EXAMPLE1) EXAMPLE1
#define EXAMPLE3(EXAMPLE1, _, __) ( EXAMPLE1 ? _(__) : false )

int main() {
    /* examples */
    DUMP_MACRO(EXAMPLE);
    DUMP_MACRO(EXAMPLE0, 0);
    DUMP_MACRO(EXAMPLE1, 1);
    DUMP_MACRO(EXAMPLE3, 3);
    DUMP_MACRO(EXAMPLE3(EXAMPLE, EXAMPLE1, non_macro_symbol));
    /* does not work for DUMP_MACRO itself, because the
       preprocessor does not allow recursion */
    DUMP_MACRO(DUMP_MACRO, 1);
    DUMP_MACRO(DUMP_MACRO, 2);
    return 0;
}

Le programme imprime:

'EXAMPLE' expands to '( 4 << 9 )'
'EXAMPLE0()' expands to '4'
'EXAMPLE1(<1>)' expands to '<1>'
'EXAMPLE3(<1>, <2>, <3>)' expands to '( <1> ? <2>(<3>) : false )'
'EXAMPLE3(EXAMPLE, EXAMPLE1, non_macro_symbol)' expands to '( ( 4 << 9 ) ? non_macro_symbol : false )'
'DUMP_MACRO(<1>)' expands to 'DUMP_MACRO (<1>)'
'DUMP_MACRO(<1>, <2>)' expands to 'DUMP_MACRO (<1>, <2>)'

Cependant, cela ne donne que le full expansion. Si vous avez besoin de simples étapes, Eclipse/CDT peut vous aider, mais uniquement si vous lui apprenez tous les en-têtes et les indicateurs de compilateur utilisés.

9
not-a-user
gcc -E myfile.c
4
Markus Schnell

Si vous utilisez gcc, vous pouvez aussi lancer

cpp myfile.c
3
qrdl

De nombreux IDE vous montreront la version développée de la macro dans l'éditeur lorsque le pointeur de la souris passe au-dessus de l'identifiant (ou d'une autre manière). Je sais que Eclipse/CDT le fait, et Visual Studio le fait (au moins, VS 2008 le fait).

Il peut être utile de faire en sorte que le compilateur génère une sortie prétraitée si vous recherchez un problème épineux, mais utilisez-le jour après jour pour savoir ce qui se passe avec le code sur votre écran, en utilisant le IDE est le chemin à parcourir.

3
Michael Burr

gcc même avec -E a besoin du chemin des fichiers d'en-tête ... comme -I _path_to_your_headers ... 

Si vous avez un Makefile, en général, ce que vous pourriez faire est de surcharger CC avec gcc -E

Généralement, cpp n'est qu'un script qui ajoute des indicateurs à gcc pour le préprocesseur, comme d'habitude ...

3
LB40

Vous voulez exécuter uniquement l’étape preprocessor de votre compilateur, chargée de l’extension des macros. Pour gcc, il s'agit de "gcc -E", mais je ne suis pas sûr des autres compilateurs.

2
Andrew Jaffe

Essayez d’exécuter cpp sur votre fichier source

2
Alex Brown

Avez-vous essayé d'exécuter gcc -E plusieurs fois jusqu'à ce qu'il n'y ait plus de macros?

1
Earlz

Lorsque piégé dans un IDE sommaire, essayez quelque chose comme

#define DISPLAY_VALUE2(x) #x
#define DISPLAY_VALUE(x) DISPLAY_VALUE2(x)
#pragma message("#DEFINE F_CPU " DISPLAY_VALUE(F_CPU))

produire

…/sketch_may21a.ino: In function 'void loop()':
…/sketch_may21a.ino:10:54: note: #pragma message: #DEFINE F_CPU 16000000L
#pragma message("#DEFINE F_CPU " DISPLAY_VALUE(F_CPU))
                                                     ^

grâce à "mdematos" sur http://MicroChip.com/forums/m724722.aspx

0
devon