指向匿名联合的指针转换在 C11 中有效吗?

Is cast of pointer to anonymous union valid in C11?

const Boo *constBoo;
Boo *nonConstBoo;

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

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

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

Cast to a union is a GNU C extension. The C standard only defines casts among scalar types (i.e., integers, floats, and pointers; see 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":

Unless the type name specifies a void type, the type name shall specify atomic, qualified, or unqualified scalar type, and the operand shall have scalar type.

您的类型是 union 类型,因此这是违反约束的,任何 C 编译器都不应该接受它。

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

在大多数情况下,当您使用此类强制转换的指针时,程序的行为是未定义的,可能会发生非常糟糕的事情。