C 如何将函数放入宏中?
正在生成错误,我不知道原因。有人能帮忙吗 编辑:错误如图所示C 如何将函数放入宏中?,c,C,正在生成错误,我不知道原因。有人能帮忙吗 编辑:错误如图所示 #define cubem(a) (a * a * a) 因为这样调用了cubem(-a),所以cubem定义应该避免副作用 hw02q2.c:42:31: warning: multiple unsequenced modifications to 'a' [-Wunsequenced] printf("cubem = %d\n", cubem(--a));
#define cubem(a) (a * a * a)
因为这样调用了
cubem(-a)
,所以cubem定义应该避免副作用
hw02q2.c:42:31: warning: multiple unsequenced modifications to 'a'
[-Wunsequenced]
printf("cubem = %d\n", cubem(--a));
^~
hw02q2.c:4:19: note: expanded from macro 'cubem'
#define cubem(a) (a * a * a)
以上是gcc c的扩展,请阅读gcc文档的第章
表达式中的语句和声明
原因是
#define cubem(a) \
({ \
typeof(a) dummy_a = (a); \
dummy_a * dummy_a * dummy_a; \
})
进行文本替换,并生成
#define cubem(a) (a * a * a)
/* and later using it .... */
printf("cubem = %d\n", cubem(--a));
在一条语句中修改a
三次。根据C标准,这是未定义的行为
相比之下
printf("cubem = %d\n", (--a * --a * --a));
计算--a
一次,将结果值传递给cubef()
如果你真的想“把一个函数放在一个宏中”,那么你可以这样做
int cubef(int a) {
return a * a * a;
}
/* and later */
printf("cubef = %d\n", cubef(--a));
是什么导致了这种说法
#define cubem(a) cubef(a)
成为
printf("cubem = %d\n", cubem(--a));
这样做的问题是,对于多次使用其参数的宏,它不起作用。比如说
printf("cubem = %d\n", cubef(--a));
原因
int sq(int a) {return a * a;}
#define cubesq(a) (a * sq(a)) /* uses a more than once
被编译器视为
printf("cubesq = %d\n", cubesq(--a));
再次修改a
,并导致未定义的行为
原因很简单:预处理器进行文本替换,并修改编译器后期看到的源代码
与其“尝试将函数放入宏”,不如干脆不要使用宏。写函数。使用函数。或者使用宏,但要尊重它们的局限性(即它们不像函数那样工作,即使它们看起来像函数)。C宏执行文本替换:每个实例都替换为宏定义,宏参数名称替换为实例参数的确切文本 定义为
#define cubem(a)(a*a*a)
的cubem
宏将按以下方式展开:
cubem(-a)
->(-a*--a*--a)
在同一表达式中多次修改a
具有未定义的行为。您无法通过便携方式解决此问题。如果您足够熟悉并且不介意依赖于不可移植的构造,您可以尝试使用编译器扩展
实现函数并使其内联扩展的正确方法是通过内联函数定义:
printf("cubem = %d\n", (--a * cubesq(--a));
还要注意,宏还有其他问题:
cubem(1+1)
扩展为(1+1*1+1*1+1)
,计算结果为4,而不是8
为避免此问题,所有宏参数都应加括号:
static inline cubem(int a) { return a * a * a; }
但这个定义仍然不支持有副作用的论点:
cubem(getchar())
将从标准输入读取3个字节。“生成错误,我不知道原因”。请显示您得到的确切错误,以便我们可以更容易地告诉您原因。它已随错误更新。我没有看到错误,只是警告与宏本身无关。不使用宏也可以得到相同的结果(如果愿意,可以尝试)。看,这不是宏的问题,而是如何使用宏的问题。不要在单个语句中使用前置/后置递增/递减。typeof
不是标准的C。它是特定于编译器的扩展。用({
/})
包装东西也不允许宏在标准C中给出dummy\u a*dummy\u a*dummy\u a
的值。当我用你的代码替换我的代码时,它可以工作,但我不理解它为什么工作,或者为什么使用“dummy\u a”或“typeof(a)”。你能解释更多吗?很好的尝试,但是如果作为cubem(dummy_a)
调用,上面的宏将失败。这种练习对于教学目的来说很有趣,但结论应该是编写内联函数。尝试将函数放入宏中的好方法;-)
static inline cubem(int a) { return a * a * a; }
#define cubem(a) ((a) * (a) * (a))