之前看到过一句话,说在C语言中几乎每一个#define宏定义都是代码的一个缺陷。
但是之前看到有个项目,包括在Linux Kernel里面,在代码中都有使用#define Func() do{} while(0)这种结构来定义被多次调用的而函数。
参考文章:
这个博客将对这个结构的宏定义函数进行总结和思考。
1、#define宏定义函数
#include "906h.h"
#include "stdio.h"
#define addDefine(a, b, val) do { \
val = a + b; \
} while(0)
int main()
{
int a,b;
printf("input two number:");
scanf("%d %d", &a, &b);
char addDefineVal = 0;
addDefine(a, b, addDefineVal);
printf("the defineAdd sum is = %d\n", addDefineVal);
printf("the inlineAdd sum is = %d\n", addInline(a,b));
return 0;
}
以宏addDefine为例。
注意这个宏函数不能定义为:
#define addDefine(a, b, val) do { \
return a + b; \
} while(0)
因为宏只是一个简单的展开,除非定义一个函数接收这个是return值,不过这样也很没有必要了。总之,别轻易return一个变量,可以return一个函数,这倒是不错的用法。
2、为什么要使用do{ } while(0) 结构来定义函数
- 避免空的宏定义引发警告
- 保证语句块是一个整体,避免if、for误识别;同时避免出现多余分号;产生错误
#include "stdio.h"
#define ERTYU() do { \
printf("This is a define func!\n");\
printf("This is a define func!\n");\
} while(0)
int main()
{
if (1)
ERTYU();
else
return 0;
return 0;
}
宏展开后为:
int main()
{
if (1)
do { printf("This is a define func!\n"); printf("This is a define func!\n");} while(0);
else
return 0;
return 0;
}
如果宏函数写成:
#define ERTYU() { \
printf("This is a define func!\n");\
printf("This is a define func!\n");\
}
那么其展开以后,将是:
int main()
{
if (1)
{ printf("This is a define func!\n"); printf("This is a define func!\n");};
else
return 0;
return 0;
}
显然,在line4最后是多出来一个分号的,在编译阶段将会报错:
没有else分支的话,不会报错,编译器会自动进行代码优化。