Ruslan
Ruslan

Reputation: 19120

Is this use of union well defined?

Consider the following code:

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);
}

Here, depending on what the ptrace call returns as the resulting prstat_iov.iov_len, prstat should be interpreted either as one structure, or as another one.

As is well known, in C++ unions can't be used as freely as in C, namely, reading an inactive member of a union results in undefined behavior. But can we consider that the ptrace call in the above code will actually act as "writing to the correct member" of the union, according to the C++ Standard, so that the above code would have well-defined behavior?

Upvotes: 2

Views: 140

Answers (1)

SergeyA
SergeyA

Reputation: 62563

In essence, the question can be rephrased in a shorter form:

union A {
   int x;
   int y;
};

A a;
my_non_cpp_function(&a);

Now the question becomes, since it is absolutely unknown to C++ compiler how would non-cpp function access the members of the union, how do we define which member of the union is active? (remember, C explicitly allows accessing inactive member)!

Answer is simple. Since interface between C++ and non-C++ constructs is not defined anyways, the properl solution is to declare union inside extern "C" block. This would ensure C linkage for the union, and, in turn, make it defined to access inactive member.

Upvotes: 2

Related Questions