我们如何编写一个 C 宏以将强制转换插入到函数调用中?



我们如何编写一个预处理器宏来用func((DemoUnion)替换

func(
的每个实例?

另外,也许是一个宏来用func((DemoUnion)替换func((DemoUnion)(DemoUnion)

顺便说一下,下面是如何定义DemoUnion的示例:

union DemoUnion {
char c;
short s;
int i;
float f;
}; typedef union DemoUnion DemoUnion;

// the typedef  allows us to declare instances by writing
//     DemoUnion instanceName;  
// instead of:
//     union DemoUnion instanceName;  

此外,C 允许我们非常轻松地转换为联合类型:
(只要对强制转换的输入是联合中包含的类型之一)

int main() {
DemoUnion big = 0;
char c  = 1;
big = (DemoUnion) c; // cast char to union type
func(big);
func((DemoUnion) c);
}

我们如何编写预处理器宏来替换以下各项的每个实例:

func(

func((DemoUnion)?

我们不会编写这样的宏,因为 C 没有办法做到这一点。 宏扩展将宏标识符以及(对于类似函数的宏)其参数列表替换为宏的替换文本。(字符不能是宏标识符的一部分,并且它本身不是参数列表。 因此,func(不是一个受宏观扩张影响的单位。

但是,您可以这样做:

#define func(x) func((DemoUnion)(x))

这将与您描述的效果有关,但它特定于参数列表长度。 此外,您不必担心递归扩展;C 指定它不会发生。

另外,也许是一个宏来替换func((DemoUnion)(DemoUnion)func((DemoUnion)

不。 宏替换替换宏,而不是常规文本模式。 无论如何,只要(DemoUnion)转换有效,(DemoUnion)(DemoUnion)也是有效且等效的。

但请注意,您有一个严重的误解:

此外,C 允许我们非常轻松地转换为联合类型:(只要 对演员表的输入是联合中包含的类型之一)

相反,C不允许转换到联合类型或从联合类型转换。完全。 一些编译器会接受这样的强制转换作为扩展,但它是非标准的。 最接近 (C2011) 标准许可证的许可证将涉及使用复合文字:

DemoUnion u = (DemoUnion) { .c = c };

请注意,尽管复合文本的部分语法类似于强制转换运算符,但那里没有强制转换。 但实际上,为什么要这样做,当您可以使用普通的初始值设定项时:

DemoUnion u = { .c = c };

。或普通成员分配:

DemoUnion u;
u.c = c;

视情况而定。

当然,反过来,您应该只使用成员选择:

char c2 = u.c;

不能用"("来定义名称。但是,您可以使用函数宏:

#define FOO(X) FOO((DemoUnion) (X))

或参数数量可变:

#define FOO(...) FOO((DemoUnion) __VA_ARGS__)

最新更新