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);
两种语言都能用。