是否明确定义了联合使用?

时间:2016-04-27 19:11:37

标签: c++ language-lawyer undefined-behavior unions

请考虑以下代码:

union
{
    PrStatus_X86_64 prstat64;
    PrStatus_X86    prstat32;
} prstat;

iovec prstat_iov = {&prstat, sizeof prstat};

if(ptrace(PTRACE_GETREGSET, tid, NT_PRSTATUS, &prstat_iov) != -1)
{
    if(prstat_iov.iov_len==sizeof prstat.prstat64)
        use(prstat.prstat64);
    else if(prstat_iov.iov_len==sizeof prstat.prstat32)
        use(prstat.prstat32);
}

此处,根据ptrace调用返回的结果prstat_iov.iov_lenprstat应该被解释为一个结构或另一个结构。

众所周知,在C ++中,联合体不能像在C中一样自由使用,即,读取联合的非活动成员会导致未定义的行为。但我们是否可以认为上述代码中的ptrace调用实际上将作为"写入正确的成员"根据C ++标准,联合,那么上面的代码会有明确的行为吗?

1 个答案:

答案 0 :(得分:2)

从本质上讲,这个问题可以用较短的形式来改写:

union A {
   int x;
   int y;
};

A a;
my_non_cpp_function(&a);

现在问题变成了,因为C ++编译器完全不知道非cpp函数如何访问union的成员,我们如何定义union的哪个成员是活动的? (记住,C明确允许访问非活动成员)!

答案很简单。由于C ++和非C ++构造之间的接口尚未定义,因此正确的解决方案是在extern "C"块内声明union。这将确保联合的C链接,并反过来使其定义为访问非活动成员。