简体   繁体   English

指向匿名联合的指针是否在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;

Is the above construct valid in C11, or is it only GCC/clang extension that you can cast a pointer to an anonymous union in this fashion? 以上构造在C11中是有效的,还是只有GCC / clang扩展,您可以以这种方式将指针强制转换为匿名联合? If it is not valid, is there any other way to write an equivalent expression in valid C11 code? 如果它无效,是否有其他方法可以在有效的C11代码中编写等效表达式?

The intention was to emulate C++ const_cast that would be C11 compatible and provide some rudimentary type safety. 目的是模拟C ++ const_cast,它将与C11兼容并提供一些基本类型的安全性。 An explicit cast from const to non-const pointer will trigger a warning with -Wcast-qual option, which is undesirable. 从const到非const指针的显式转换将使用-Wcast-qual选项触发警告,这是不合需要的。

Cast to a union is a GNU C extension. 转换为union是GNU C扩展。 The C standard only defines casts among scalar types (ie, integers, floats, and pointers; see 6.5.4p2 ). C标准仅定义标量类型中的强制转换(即整数,浮点数和指针;参见6.5.4p2 )。 What you could do, however, is copy-create the union on the spot (instead of casting to it) and then take the appropriate member: 但是,你可以做的是复制 - 在现场创建联合(而不是强制转换),然后采取适当的成员:

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

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

The above should work (in C, but not C++ where you're required to access only the last used member of a union) because qualified and non-qualified objects must have the same representation and alignment requirements and the same applies to pointers to qualified and unqualified versions of compatible types ( 6.2.5p28 ). 上面应该工作(在C中,但不是C ++,你需要只访问最后一个使用的联合成员),因为限定和非限定对象必须具有相同的表示和对齐要求,同样适用于指向限定的指针和兼容类型的不合格版本( 6.2.5p28 )。

memcpy(&nonConstBoo,&constBoo,sizeof constBoo);

should work in either language. 应该用任何一种语言。

No that is not legal for a simple reason, casts are only allowed for scalar types, C11 6.5.4 "Cast Operators": 由于一个简单的原因,这不合法,只允许使用标量类型,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. 除非类型名称指定void类型,否则类型名称应指定原子,限定或非限定标量类型,操作数应具有标量类型。

Your type is a union type so this is a constraint violation and no C compiler should ever accept this. 你的类型是一个union类型,所以这是一个约束违规,没有C编译器应该接受这个。

If you just want to cast away const ness, just do so, that is use (Boo*)constBoo . 如果你只想抛弃const ,就这样做,那就是使用(Boo*)constBoo But note that you do that on your own risk, casting a spell tells the compiler that you pretend that you know what you are doing. 但请注意,你自己承担风险,施放咒语告诉编译器你假装知道自己在做什么。

In most of the cases, the behavior of the program is undefined when you use such casted pointers, very bad things can happen. 在大多数情况下,当您使用这样的铸造指针时,程序的行为是未定义的,可能会发生非常糟糕的事情。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM