Просмотр расширенных макросов C

Если я хочу развернуть макрос C, каковы хорошие способы сделать это (помимо отслеживания его вручную)?

Например, GTK_WIDGET_SET_FLAGS, он использует макрос, который использует макрос, который использует макрос (или два)...

Я хочу просто увидеть его каким-то образом автоматическим образом, вместо поиска каждого макроса на каждом шагу.

UPDATE

Я пробовал cpp, но, похоже, только первый проход

на

GTK_WIDGET_SET_FLAGS(obj, 13)

Я получил расширенный файл include, а затем:

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

Это объясняется этим сообщением об ошибке. Я получаю это на stderr (при использовании -o filename)

gtk/gtkwidget.h:34:21: gdk/gdk.h: No such file or directory
gtk/gtkwidget.h:35:31: gtk/gtkaccelgroup.h: No such file or directory
gtk/gtkwidget.h:36:27: gtk/gtkobject.h: No such file or directory
gtk/gtkwidget.h:37:31: gtk/gtkadjustment.h: No such file or directory
gtk/gtkwidget.h:38:26: gtk/gtkstyle.h: No such file or directory
gtk/gtkwidget.h:39:29: gtk/gtksettings.h: No such file or directory
gtk/gtkwidget.h:40:21: atk/atk.h: No such file or directory

каталоги gtk, atk и gdk все находятся в текущем рабочем каталоге, поэтому как мне разрешить поиск cpp?

btw, gcc -E дает тот же самый результат, что и cpp

Update2:

Проблема с включенным путём решается с помощью gcc -E и передачи каталога include с опцией -I

Ответ 1

В зависимости от того, какой компилятор вы используете, должен быть способ увидеть код после preprocessor (который расширяет макрос, макросы вообще не известны компилятору).

В gcc опция - E. Здесь упрощенный пример, используя код игрушки, а не фактический макрос GTK +:

~/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;
}

Ответ 2

В Visual Studio вы можете сгенерировать исходный файл перевода с препроцессором. Вы можете перейти к вариантам проекта, C/С++/Preprocessor и поместить "Generate Preprocessed File" или "Preprocess to a File" в "Yes" (или использовать переключатель компилятора /P или/EP для включения номеров строк или нет).

Ответ 3

Вы можете сбросить расширение макроса во время выполнения следующим образом:

#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;
}

Программа печатает:

'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>)'

Однако это дает только расширение full. Если вам нужны отдельные шаги, Eclipse/CDT может помочь, но только если вы преподаете все заголовки и флаги компилятора, которые вы используете.

Ответ 4

gcc -E myfile.c

Ответ 5

Если вы используете gcc, вы также можете запустить

cpp myfile.c

Ответ 6

Многие IDE покажут вам расширенную версию макроса в редакторе, когда указатель мыши нависает над идентификатором (или каким-либо другим способом). Я знаю, что Eclipse/CDT делает это, и Visual Studio делает это (по крайней мере, VS 2008).

Наличие компилятора для генерации предварительно обработанного вывода может оказаться полезным, если вы отслеживаете сложную проблему, но для использования в режиме "день/день", когда вы просто хотите знать, что происходит с кодом на вашем экране, использование IDE путь.

Ответ 7

gcc даже с -E требуется путь к файлам заголовков... например -I_path_to_your_headers...

Если у вас есть Makefile, вообще-то, что вы можете сделать, это перехват CC с gcc -E

Как правило, cpp представляет собой только script, добавляя некоторые флаги в gcc для препроцессора, как традиционные...

Ответ 8

Вы хотите запустить только этап препроцессора своего компилятора, ответственный за расширение макросов. Для gcc, это "gcc -E", но я не уверен в других компиляторах.

Ответ 9

Попробуйте запустить cpp в исходном файле

Ответ 10

Вы пытались запустить gcc -E несколько раз, пока не осталось больше макросов?

Ответ 11

Попав в ловушку отрывочной IDE, попробуйте что-то вроде

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

производить

…/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))
                                                     ^

благодаря "mdematos" в http://MicroChip.com/forums/m724722.aspx