是否可以在函数内使用#define?
例如,我看到像流动的源代码。 我们可以在函数中使用#define
吗? 它是如何工作的? (更多信息:这些代码是我从openvswitch
源代码中复制的代码):
void * ofputil_put_action(enum ofputil_action_code code, struct ofpbuf *buf) { switch (code) { case OFPUTIL_ACTION_INVALID: #define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) case OFPUTIL_##ENUM: #include "ofp-util.def" OVS_NOT_REACHED(); #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \ case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ case OFPUTIL_##ENUM: return ofputil_put_##ENUM(buf); #include "ofp-util.def" } OVS_NOT_REACHED(); } #define OFPAT10_ACTION(ENUM, STRUCT, NAME) \ void \ ofputil_init_##ENUM(struct STRUCT *s) \ { \ memset(s, 0, sizeof *s); \ s->type = htons(ENUM); \ s->len = htons(sizeof *s); \ } \ \ struct STRUCT * \ ofputil_put_##ENUM(struct ofpbuf *buf) \ { \ struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ ofputil_init_##ENUM(s); \ return s; \ } #define OFPAT11_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ OFPAT10_ACTION(ENUM, STRUCT, NAME) #define OFPAT13_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ OFPAT10_ACTION(ENUM, STRUCT, NAME) #define NXAST_ACTION(ENUM, STRUCT, EXTENSIBLE, NAME) \ void \ ofputil_init_##ENUM(struct STRUCT *s) \ { \ memset(s, 0, sizeof *s); \ s->type = htons(OFPAT10_VENDOR); \ s->len = htons(sizeof *s); \ s->vendor = htonl(NX_VENDOR_ID); \ s->subtype = htons(ENUM); \ } \ \ struct STRUCT * \ ofputil_put_##ENUM(struct ofpbuf *buf) \ { \ struct STRUCT *s = ofpbuf_put_uninit(buf, sizeof *s); \ ofputil_init_##ENUM(s); \ return s; \ } #include "ofp-util.def"
#define
是一个预处理程序指令 :它用于生成最终的C ++代码, 然后将其处理到将生成可执行文件的编译器 。 因此代码如下:
for(int i = 0; i < 54; i++) { #define BUFFER_SIZE 1024 }
未执行54次(在预处理器级别):预处理器只是在for
循环上运行(不知道for
循环是什么),看到一个define语句,将1024
与BUFFER_SIZE
关联并继续。 直到它到达文件的底部。
您可以在任何地方编写#define
,因为预处理器并不真正了解程序本身。
当然这是可能的。 #define
在编译器执行任何操作之前由预处理器处理。 这是一个简单的文本替换。 预处理器甚至不知道代码行是在函数,类或其他内部还是外部。
顺便说一句,在C ++中定义预处理器宏通常被认为是不好的风格。 使用模板可以更好地实现大多数用于它们的东西。
它是如何工作的? 所有C / C ++文件首先由…… 预处理器处理 。
它对C和C ++语法一无所知。 它只是用ANOTHER THING
取代THIS_THING
。 这就是为什么你也可以在函数中放置#define
的原因。
当然。 #define
由预处理器处理,在编译器有任何代码行在函数内部,内部参数列表,内部数据结构等之前就已经发生了。
由于预处理器没有C ++函数的概念,因此它也意味着宏定义没有自然的范围。 因此,如果要重用宏名称,则必须#undef NAME
以避免出现警告。
您可以在函数内部使用它,但它不是作用于函数。 因此,在您的示例中,宏的第二个定义将是重新定义并生成错误。 您需要先使用#undef
清除它们。
您可以在任何地方使用#define
。 它不了解function,也不受其范围的约束。 当预处理器从上到下扫描文件时,它会在看到它们时处理#define
。 不要误导(通过像这样的愚蠢代码!)认为只有在调用函数时才会以某种方式处理#define
; 不是。