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

时间:2018-01-24 21:48:23

标签: c casting macros parameter-passing c-preprocessor

我们如何编写预处理器宏来替换每个实例:
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允许我们很容易地转换为联合类型:
(只要演员的输入是联盟中包含的类型之一)

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

  func(big);
  func((DemoUnion) c);
}

2 个答案:

答案 0 :(得分:2)

  

我们如何编写预处理器宏来替换:

的每个实例
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;

答案 1 :(得分:0)

无法使用"("定义名称)。但是,您可以使用函数宏:

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

或使用可变数量的参数:

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