const Boo *constBoo;
Boo *nonConstBoo;

nonConstBoo = ((union {const Boo *_q; Boo *_nq;})constBoo)._nq;

上面的构造在c11中有效吗,还是只有gcc/clang扩展才能以这种方式将指针投射到匿名联合?如果它无效,是否有其他方法可以用有效的c11代码编写等效表达式?
目的是模仿C++COSTYSTCAST,这将是C11兼容,并提供一些基本类型的安全性。从const到non const指针的显式强制转换将触发带有-wcast qual选项的警告,这是不可取的。

最佳答案

Cast to a union是gnu c的扩展。c标准仅定义标量类型(即整数、浮点和指针;请参见6.5.4p2)之间的强制转换。但是,您可以做的是当场复制创建联合(而不是强制转换到它),然后获取相应的成员:

typedef struct Boo Boo;
const Boo *constBoo;
Boo *nonConstBoo;

int main()
{
    nonConstBoo = (union {const Boo *_q; Boo *_nq;}){._q=constBoo}._nq;
}

上面应该工作(在C,而不是C++中,您只需要访问联盟的最后一个使用成员),因为合格的和不合格的对象必须具有相同的表示和对齐要求,同样适用于兼容类型的合格和不合格版本的指针(6.2.5p28)。
memcpy(&nonConstBoo,&constBoo,sizeof constBoo);

两种语言都能用。

09-09 20:38