作为您的问题的一种可能解决方案:“编写一个宏,然后通过替换为等效函数将其丢弃”,您可以使用原型函数式宏。它们有一些限制,必须小心使用。但它们的工作方式几乎与函数相同。
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA
xxPseudoPrototype(float, xxSUM_data, int x; float y; );
xxSUM_data xxsum;
#define SUM_intfloat(X, Y) ( xxsum = (xxSUM_data){ .x = (X), .y = (Y) }, \
xxsum.xxmacro__ret__ = xxsum.x + xxsum.y, \
xxsum.xxmacro__ret__)
我已经在这里解释了细节(主要是第 4 节,用于类似函数的宏):
Macros faking functions
- 第一行定义了一个宏,可用于为宏声明 pseudoprototypes。
- 第二行使用提供这种伪原型的宏。它定义了所需类型的“正式”参数。它依次包含宏所需的“返回”类型,将保存宏参数的结构的名称,最后是宏的参数(带有类型!)。我更喜欢称它们为伪参数。
- 第 3 行是强制性声明,它使 伪参数“真实”。它声明了一个结构,它是有必要编写的。它定义了一个包含 pseudoparameters 的“真实”版本的结构。
- 最后,宏本身被定义为表达式的链表,用逗号分隔。第一个操作数用于将宏的参数“加载”到“真实”类型参数中。最后一个操作数是“返回值”,它也具有所需的类型。
观察编译器对类型进行正确且透明的诊断。
(但是,如链接中所述,有必要注意这些构造)。
现在,如果您可以将宏的所有句子收集为以逗号分隔的函数调用链,那么您可以根据需要获得类似函数的宏。
此外,您可以轻松地将其转换为真正的函数,因为参数列表已经定义。类型检查已经完成,所以一切都会正常工作。
在上面的示例中,您必须将所有行(第一行除外)替换为其他行:
#define xxPseudoPrototype(RETTYPE, MACRODATA, ARGS) typedef struct { RETTYPE xxmacro__ret__; ARGS } MACRODATA
float SUM_intfloat(int x, float y) { /* (1) */
xxPseudoPrototype(float, xxSUM_data, int x; float y; ); /* (2) */
xxSUM_data xxsum; /* (2) */
return /* (3) */
( xxsum = (xxSUM_data){ .x = x, .y = y }, /* (4) (5) (6) */
xxsum.xxmacro__ret__ = xxsum.x + xxsum.y, /* (5) (6) */
xxsum.xxmacro__ret__) /* (6) */
; /* (7) */
} /* (8) */
替换将遵循系统程序:
(1) 宏头变成函数头。分号 (;) 替换为逗号 (,)。
(2) 声明行移到函数体内。
(3) 增加了“回”字。
(4) 宏参数 X, Y, 替换为函数参数 x, y。
(5) 删除所有结尾的“\”。
(6) 所有中间计算和函数调用都保持不变。
(7) 添加分号。
(8) 关闭函数体。
问题:虽然这种方法可以解决您的需求,但请注意该函数复制了它的参数列表。这不好:必须删除伪原型和重复项:
float SUM_intfloat(int x, float y) {
return
( x + y )
;
}