问题
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? If it is not valid, is there any other way to write an equivalent expression in valid C11 code?
The intention was to emulate C++ const_cast that would be C11 compatible and provide some rudimentary type safety. An explicit cast from const to non-const pointer will trigger a warning with -Wcast-qual option, which is undesirable.
回答1:
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). 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).
memcpy(&nonConstBoo,&constBoo,sizeof constBoo);
should work in either language.
回答2:
No that is not legal for a simple reason, casts are only allowed for scalar types, 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.
Your type is a union
type so this is a constraint violation and no C compiler should ever accept this.
If you just want to cast away const
ness, just do so, that is use (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.
来源:https://stackoverflow.com/questions/51231405/is-cast-of-pointer-to-anonymous-union-valid-in-c11