How are conversions applied to bit-field types in conditional operators?

Viewed 149

The following code prints int when compiled for x86_64 with Clang, and unsigned int with GCC.

I am not sure which (if either) is correct.

#include <stdio.h>
struct s {
    unsigned int x : 1;
};

template<typename T>
void f(T) {}

template<> void f<int>(int) {
    printf("int\n");
}

template<> void f<unsigned int>(unsigned int) {
    printf("unsigned int\n");
}

struct s r;
int main()
{
    f(0 ? r.x : 0);
}

If we replace the conditional with (r.x + 0) both compilers say the type is signed.

The C++ standard section expr.cond has a number of rules for conversion, but none of the cases seem to cover the issue of a conversion between a glvalue and a prvalue of different types.

Is it implementation-defined whether unsigned bitfields are promoted to signed ints?

1 Answers

Clang is correct: the usual arithmetic conversions are applied just as for + ([expr.cond]/7.2) and promote the bit-field to int because it can represent all its values ([expr.arith.conv]/1.5, [conv.prom]/5, noting that the lvalue-to-rvalue conversion has already been applied ([expr.cond]/7, before the bullets)).

Related