是通过union未定义的行为进行const-casting吗?

Ker*_* SB 17 c const unions language-lawyer

与C++不同,C没有概念const_cast.也就是说,没有有效的方法将const限定指针转换为非限定指针:

void const * p;
void * q = p;    // not good
Run Code Online (Sandbox Code Playgroud)

首先:这个演员实际上是未定义的行为吗?

无论如何,GCC警告这一点.要制作需要const-cast的"干净"代码(即我可以保证我不会改变内容,但我所拥有的只是一个可变指针),我看到了以下"转换"技巧:

typedef union constcaster_
{
    void * mp;
    void const * cp;
} constcaster;
Run Code Online (Sandbox Code Playgroud)

用法:u.cp = p; q = u.mp;.

通过这种联盟抛弃常量的C语言规则是什么?我对C的了解只是非常不完整,但我听说C对联合访问比C++要宽松得多,所以虽然我对这个结构有一种不好的感觉,但我想从标准中得到一个论证(C99我想,虽然如果在C11中这已经改变了,那么知道它会很好.

Lin*_*cer 10

它的实现已定义,参见C99 6.5.2.3/5:

如果在对象的最新存储是另一个成员时使用union对象的成员的值,则该行为是实现定义的.

更新: @AaronMcDaid评论说,毕竟这可能是明确定义的.

该标准规定了以下6.2.5/27:

同样,指向兼容类型的限定或非限定版本的指针应具有相同的表示和对齐要求.27)

27)相同的表示和对齐要求意味着可互换性作为函数的参数,函数的返回值和联合的成员.

(6.7.2.1/14):

指向联合对象的指针(适当转换)指向其每个成员(或者如果成员是位域,则指向它所在的单位),反之亦然.

有人可能会得出结论,在这种特殊情况下,只有一种方法可以访问联合中的元素.

  • +1为OP问题的直接答案:) (2认同)