如果在宏中声明变量会发生什么?

R.D*_*.D. 4 c c++

假设我有一个宏定义如下:

#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里面的内部?我可以使用哪些技巧来保证任何类型的唯一性(除了使变量内部有一个乱码,这使得其他人不太可能使用相同的名称)?

(理想情况下,函数对此更有用,但我的特殊情况不允许这样做)

Sha*_*fiz 7

如果我们考虑变量的范围,则可以保证do..while()内的a,b与外部定义的不同.

对于您的情况,do..while()内部不存在a,b定义的外部.

使用MACRO时需要注意很多事情.


VGE*_*VGE 6

宏只执行字符串替换.语义很低,编译器对预处理器的了解有限(实际上#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不会返回你想要的东西.

  • 在C中,创建(内联)函数.不要使用类似函数的宏. (2认同)