【发布时间】:2013-12-27 01:46:29
【问题描述】:
你能告诉我这个C“函数宏”有什么问题吗?
#define foo(P,I,X) do { (P)[I] = X; } while(0)
我的目标是 foo 对于任何 POD 数据类型 T(即 int、float*、struct my_struct { int a,b,c; })的行为与以下函数 foofunc 完全相同:
static inline void foofunc(T* p, size_t i, T x) { p[i] = x; }
例如这是正常工作:
int i = 0;
float p;
foo(&p,i++,42.0f);
它可以处理像&p 这样的事情,因为将P 放在括号中,它确实增加i 一次,因为I 在宏中只出现一次,并且它需要在行尾使用分号到期到do {} while(0)。
是否还有其他我不知道且宏 foo 的行为与函数 foofunc 不同的情况?
在 C++ 中,可以将 foofunc 定义为模板,并且不需要宏。但我正在寻找一种适用于普通 C (C99) 的解决方案。
【问题讨论】:
-
出于好奇,当
foofunc将被内联时,为什么要使用宏?尽管使用指针存在风险,但不会有任何性能优势。 -
foofunc 仅适用于类型 T,因此每个类型需要一个定义。如果我想要 int、float* 和 my_struct 的 foofunc,我需要 foofunc_int、foofunc_floatptr、foofunc_my_struct。该宏适用于任何类型。
-
这就是模板的用途。只需在你的函数定义之前加上
template <typename T>,它就会像你想要的那样工作。 -
@parkovski:这个问题是关于 C,而不是 C++。所以没有模板:(
-
@OliCharlesworth 提到了一个很好的观点,其中奇怪的参数实际上被编译了。如果你用括号括起来,那应该可以解决所有可能的参数问题(至少是我能想象到的)(即你的宏是
(P)[(I)] = (X))。