-
在看linux内核代码时会看到一些结构体中包含宏定义:
第一次看到觉得怪怪的,虽然我知道宏定义作用于开始定义处,结束于#undef。网上也看到一些人的疑问,比如:点击(此处)折叠或打开
-
struct i2c_msg {
-
__u16 addr; /* slave address */
-
__u16 flags;
-
#define I2C_M_TEN 0x0010 /* this is a ten bit chip address */
-
#define I2C_M_RD 0x0001 /* read data, from slave to master */
-
#define I2C_M_NOSTART 0x4000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-
#define I2C_M_REV_DIR_ADDR 0x2000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-
#define I2C_M_IGNORE_NAK 0x1000 /* if I2C_FUNC_PROTOCOL_MANGLING */
-
#define I2C_M_NO_RD_ACK 0x0800 /* if I2C_FUNC_PROTOCOL_MANGLING */
-
#define I2C_M_RECV_LEN 0x0400 /* length will be first received byte */
-
__u16 len; /* msg
length */
-
__u8 *buf; /* pointer to msg
data */
- };
-
struct i2c_msg {
a) 如果去定义这样的结构体变量,会不会导致一个宏重复定义。
b) 既然这样没错误,那么有什么好处。
2. 通过看如下程序预编译后的结果:
点击(此处)折叠或打开
-
struct mystruct {
-
#define XPOS 1
-
#define YPOS 2
-
int a;
-
char b;
-
};
-
-
int main(void)
-
{
-
struct
mystruct ex1 = {2, 'a'};
-
struct
mystruct ex2 = {3, 'b'};
-
ex1.a=XPOS;
-
ex2.a=YPOS;
-
-
return 0;
- }
gcc main.c -E > main.E预编译后:
点击(此处)折叠或打开
-
# 1 "main.c"
-
# 1 ""
-
# 1 ""
-
# 1 "main.c"
-
-
-
struct
mystruct {
-
-
-
int a;
-
char b;
-
};
-
-
int main(void)
-
{
-
struct
mystruct ex1 = {2, 'a'};
-
struct
mystruct ex2 = {3, 'b'};
-
ex1.a=1;
-
ex2.a=2;
-
-
-
-
return 0;
- }
由此可见,我和存在上述2点疑问的人都忘记预编译和编译的作用时间不同。预编译时,宏被展开,宏定义处被拿掉了,所以接下来再用struct mystruct 来定义变量时,里面的宏已经不存在了,所以并不会导致一个宏重复被定义。至于这样编写代码的好处,有人说是增加代码的可阅读性,让人知道这些宏只会用于这个结构体中,还有就是便于对这个结构体进行扩展。
本文探讨了在Linux内核代码中结构体内部包含宏定义的现象,解释了这种做法不会导致宏重复定义的问题,并阐述了其潜在的好处。通过实例展示了宏定义如何在预编译过程中发挥作用,确保代码的正确性和灵活性。

435

被折叠的 条评论
为什么被折叠?



