假设我有一个宏定义如下:
#define FOO(x,y) \
do {
int a,b;
a = f(x);
b = g(x);
y = a+b;
} while (0)
扩展宏时,GCC是否"保证"a,b的任何一种唯一性?我的意思是,如果我以下列方式使用FOO:
int a = 1, b = 2; FOO(a,b);
之后,预处理将是:
int a = 1, b = 2;
do {
int a,b;
a = f(a);
b = g(b);
b = a+b;
} while (0)
编译器是否可以区分ado {}和ainside里面的内部?我可以使用哪些技巧来保证任何类型的唯一性(除了使变量内部有一个乱码,这使得其他人不太可能使用相同的名称)?
(理想情况下,函数对此更有用,但我的特殊情况不允许这样做)
如果我们考虑变量的范围,则可以保证do..while()内的a,b与外部定义的不同.
对于您的情况,do..while()内部不存在a,b定义的外部.
使用MACRO时需要注意很多事情.
宏只执行字符串替换.语义很低,编译器对预处理器的了解有限(实际上#pragma实际上不是预处理器关键字和源代码行信息).
在您的情况下,a和b不是初始化的本地值.行为是不可预测的.您的扩展代码等效于以下代码.
int a = 1, b = 2;
do {
int a___,b___;
a___ = f(a___);
b___ = g(b___);
b___ = a___+b___;
} while (0)
Run Code Online (Sandbox Code Playgroud)
为了避免在c ++中出现这种情况,更喜欢使用内联函数或模板.如果使用ac 1999兼容编译器,则可以使用c语言内联. http://en.wikipedia.org/wiki/Inline_function
在c中,您可以通过()定义更长的变量和周围参数来制作更安全的宏:
#define FOO(x,y) \
do {
int FOO__a,FOO__b;
FOO__a = f(x);
FOO__b = g(x);
y = FOO__a+FOO__b + (y)*(y);
} while (0)
Run Code Online (Sandbox Code Playgroud)
注意:我通过添加(y)*(y)来改变你的例子来说明这种情况
仅使用一次宏参数也是一种好习惯.这可以防止这样的副作用:
#define max(a,b) a>b?a:b
max(i++,--y)
Run Code Online (Sandbox Code Playgroud)
Max不会返回你想要的东西.