我们如何编写预处理器宏来替换以下各项的每个实例:
func(
具有
func((DemoUnion)
另外,也许可以用一个宏将func((DemoUnion)(DemoUnion)替换为func((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允许我们非常容易地转换为联合类型:
(只要对cast的输入是union中包含的类型之一)
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允许我们非常容易地转换为联合类型:
cast的输入是union中包含的类型之一)
相反,C不允许向或从并集类型进行铸造。完全。有些编译器将接受这种类型转换作为扩展,但它是非标准的。最接近的(c211)标准许可将涉及使用复合文字:
DemoUnion u = (DemoUnion) { .c = c };

请注意,尽管复合文字的部分语法类似于强制转换运算符,但那里没有强制转换。但实际上,当你可以使用一个普通的初始值设定项时,为什么要这样做呢
DemoUnion u = { .c = c };

... 或普通成员转让:
DemoUnion u;
u.c = c;

如情况所需。
当然,换个角度来说,您应该只使用成员选择:
char c2 = u.c;

关于c - 我们将如何编写一个C宏以将强制类型转换插入函数调用中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48432180/

10-09 10:15