c预处理程序-看到扩展的C宏
如果要扩展C宏,有什么好的方法(除了手动跟踪之外)?
例如gcc -E,它使用的宏使用的宏使用一个(或两个)宏...
我只想看到它以某种方式自动扩展,而不是在过程的每个步骤中搜索每个宏。
更新
我尝试了cpp,但它似乎只进行了第一遍
上:
GTK_WIDGET_SET_FLAGS(obj, 13)
我扩展了包含文件,然后:
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完全相同的输出
更新2:
包含路径问题是通过使用gcc -E并通过-I选项传递包含目录来解决的
hasen asked 2020-06-20T20:18:57Z
11个解决方案
62 votes
根据您使用的编译器,应该有一种方法可以在预处理器(进行宏扩展,编译器根本不知道宏)之后查看代码。
对于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 ""
# 1 ""
# 1 "cpptest.c"
int main(void)
{
((0)->flags |= (4711));
return 0;
}
unwind answered 2020-06-20T20:19:15Z
13 votes
在Visual Studio中,您可以生成预处理器结果翻译单元文件。 您可以转到项目选项C / C ++ / Preprocessor,然后将“ Generate Preprocessed File”或“ Preprocess to a File”放到Yes(或使用/ P或/ EP编译器开关是否包含行号)上。
Cătălin Pitiș answered 2020-06-20T20:19:35Z
9 votes
您可以在运行时像这样转储宏的扩展:
#include
/*
* 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>)'
但是,这仅产生全部扩展。 如果只需要一步,Eclipse / CDT可以提供帮助,但前提是您必须教给它使用的所有标头和编译器标志。
not-a-user answered 2020-06-20T20:20:04Z
4 votes
gcc -E myfile.c
Markus Schnell answered 2020-06-20T20:20:20Z
3 votes
如果您使用gcc,也可以运行
cpp myfile.c
qrdl answered 2020-06-20T20:20:39Z
3 votes
当鼠标指针悬停在标识符上(或其他方式)时,许多IDE都会在编辑器中向您显示宏的扩展版本。 我知道Eclipse / CDT可以做到这一点,而Visual Studio可以做到这一点(至少VS 2008可以做到)。
如果您要跟踪一个棘手的问题,则让编译器生成预处理的输出会很有用,但是对于日复一日的使用,您只想知道屏幕上代码的状态,使用IDE是一种方法 走。
Michael Burr answered 2020-06-20T20:21:04Z
3 votes
gcc甚至带有-E也需要头文件的路径...就像-I _path_to_your_headers ...
通常,如果您有一个Makefile,则可以用gcc -E覆盖CC。
通常,cpp只是一个脚本,向预处理器的gcc添加一些标志,就像传统的...
LB40 answered 2020-06-20T20:21:33Z
2 votes
您只想运行编译器的预处理器阶段,负责扩展宏。 对于gcc,这是“ gcc -E”,但是我不确定其他编译器。
Andrew Jaffe answered 2020-06-20T20:21:53Z
2 votes
尝试在源文件上运行cpp
Alex Brown answered 2020-06-20T20:22:13Z
1 votes
您是否尝试过多次运行gcc -E直到不再有宏?
Earlz answered 2020-06-20T20:22:33Z
0 votes
当困在粗略的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))
^
感谢[http://MicroChip.com/forums/m724722.aspx]上的“ mdematos”
devon answered 2020-06-20T20:23:01Z