c语言宏扩展的过程,c预处理程序-看到扩展的C宏

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值