是否可以在函数内使用#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语句,将1024BUFFER_SIZE关联并继续。 直到它到达文件的底部。

您可以在任何地方编写#define ,因为预处理器并不真正了解程序本身。

当然这是可能的。 #define在编译器执行任何操作之前由预处理器处理。 这是一个简单的文本替换。 预处理器甚至不知道代码行是在函数,类或其他内部还是外部。

顺便说一句,在C ++中定义预处理器宏通常被认为是不好的风格。 使用模板可以更好地实现大多数用于它们的东西。

它是如何工作的? 所有C / C ++文件首先由…… 预处理器处理

它对C和C ++语法一无所知。 它只是用ANOTHER THING取代THIS_THING 。 这就是为什么你也可以在函数中放置#define的原因。

当然。 #define由预处理器处理,在编译器有任何代码行在函数内部,内部参数列表,内部数据结构等之前就已经发生了。

由于预处理器没有C ++函数的概念,因此它也意味着宏定义没有自然的范围。 因此,如果要重用宏名称,则必须#undef NAME以避免出现警告。

您可以在函数内部使用它,但它不是作用于函数。 因此,在您的示例中,宏的第二个定义将是重新定义并生成错误。 您需要先使用#undef清除它们。

您可以在任何地方使用#define 。 它不了解function,也不受其范围的约束。 当预处理器从上到下扫描文件时,它会在看到它们时处理#define 。 不要误导(通过像这样的愚蠢代码!)认为只有在调用函数时才会以某种方式处理#define ; 不是。