指向匿名联合的指针是否在C11中有效?

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

以上构造在C11中是有效的,还是只有GCC / clang扩展可以以这种方式将指针强制转换为匿名联合? 如果它无效,还有其他方法可以在有效的C11代码中编写等效表达式吗?

目的是模拟C ++ const_cast,它将与C11兼容并提供一些基本类型的安全性。 从const到非const指针的显式转换将使用-Wcast-qual选项触发警告,这是不合需要的。

转换为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); 

应该用任何一种语言工作。

由于一个简单的原因,这不合法,只允许使用标量类型,C11 6.5.4“Cast Operators”:

除非类型名称指定void类型,否则类型名称应指定原型,限定或非限定标量类型,操作数应具有标量类型。

你的类型是一个union类型,所以这是一个约束违规,没有C编译器应该接受这个。

如果你只想抛弃const ,那就这样做,那就是使用(Boo*)constBoo 。 但请注意,你自己承担风险,施放法术告诉编译器你假装知道自己在做什么。

在大多数情况下,当您使用这样的铸造指针时,程序的行为是未定义的,可能会发生非常糟糕的事情。