#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"
答案 0 :(得分:22)
#define
是一个预处理程序指令:它用于生成最终的C ++代码,然后将其处理到将生成可执行文件的编译器。因此代码如下:
for(int i = 0; i < 54; i++) {
#define BUFFER_SIZE 1024
}
不执行54次(在预处理器级别):预处理器只是在for
循环上运行(不知道for
循环是什么),看到定义语句,将1024
与BUFFER_SIZE
关联并继续。直到它到达文件的底部。
您可以在任何地方编写#define
,因为预处理器并不真正了解程序本身。
答案 1 :(得分:8)
当然这是可能的。在编译器执行任何操作之前,预处理器会处理#define
。这是一个简单的文本替换。预处理器甚至不知道代码行是在函数,类之内还是之外。
顺便说一下,在C ++中定义预处理器宏通常被认为是不好的风格。使用模板可以更好地实现它们所用的大部分内容。
答案 2 :(得分:2)
它是如何工作的?所有C / C ++文件首先由...... 预处理器处理。
它对C和C ++语法一无所知。它只是将THIS_THING
替换为ANOTHER THING
。这就是为什么你也可以在函数中放置#define
。
答案 3 :(得分:2)
不确定。 #define
由预处理器处理,在编译器有任何代码行在函数内部,内部参数列表,内部数据结构等之前发生。
由于预处理器没有C ++函数的概念,因此它也意味着宏定义没有自然的范围。因此,如果要重用宏名称,则必须#undef NAME
以避免警告。
答案 4 :(得分:2)
您可以在函数内部使用它,但它不限于该函数。因此,在您的示例中,宏的第二个定义将是重新定义并生成错误。您需要先使用#undef
清除它们。
答案 5 :(得分:1)
您可以在任意位置使用#define
。它不了解功能,也不受其范围的约束。当预处理器从上到下扫描文件时,它会在看到它们时处理#define
。不要被误导(通过像这样的愚蠢代码!)认为只有在调用函数时才会以某种方式处理#define
;不是。