加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-16 10:50:40 所属栏目:百科 来源:网络整理
导读:假设我有一个宏定义如下: #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;
假设我有一个宏定义如下:

#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)

编译器可以/将区分do {}外部和do内部吗?我可以使用哪些技巧来保证任何类型的唯一性(除了使变量内部有一个乱码,这使得其他人不太可能使用相同的名称)?

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

解决方法

宏只执行字符串替换.语义很低,编译器对预处理器的了解有限(实际上#pragma实际上不是预处理器关键字和源代码行信息).

在您的情况下,a和b不是初始化的本地值.行为是不可预测的.
您的扩展代码等效于以下代码.

int a = 1,b = 2;
do {
  int a___,b___;
  a___ = f(a___);
  b___ = g(b___);
  b___ = a___+b___;
} while (0)

为了避免这种情况,c更喜欢使用内联函数或模板.
如果使用符合c 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)

注意:我通过添加(y)*(y)来改变你的例子来说明这种情况

仅使用一次宏参数也是一种好习惯.
这可以防止这样的副作用:

#define max(a,b) a>b?a:b
max(i++,--y)

Max不会返回你想要的东西.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读