Тип lvalue.bitfield, когда базовый тип битового поля не является int в C

Кто-то обратил мое внимание на следующую программу:

#include 

struct X50 {
 long long int z:50;
} s50 = { 2 };

struct X10 {
 long long int z:10;
} s10 = { 2 };

int main() {
  printf("%zu %zu %zu\n",sizeof(long long int),sizeof(s10.z+1),sizeof(s50.z+1));
}

Тип выражения sizeof (lv.z + 1) вычисляется согласно «обычному арифметические преобразования », которые в значительной степени говорят о том, что размер типа для lvalue lv.z будет отражаться на типе добавления, если он не меньше int .

Я не ожидал, что этот тип будет зависеть от размера битового поля, но это так: и GCC, и Clang печатают 8 4 8 на моем компьютере.

Соответствующие предложения, которые я нашел в стандарте C99 есть пункт 2 в 6.3.1.1, который, похоже, ничего не говорит о битовых полях, не основанных на _Bool , int , signed int или unsigned int . Вторая часть предложения: «Если int может представлять все значения исходного типа, значение преобразуется в int ,. ..", похоже, применяется только в условиях, описанных в первой части предложения, которые не включают битовые поля на основе long long int .

Кроме того, в 6.7.2.1 говорится:

Немного -field должен иметь тип, который является квалифицированной или неквалифицированной версией _Bool, signed int, unsigned int или каким-либо другим типом, определяемым реализацией.

Так ли это, что поскольку long long int битовые поля выходят за рамки стандарта, компиляторы могут изобретать свои собственные правила, или можно найти какое-то оправдание поведения Clang и GCC в другом месте в C99?

Я обнаружил это вопрос на StackOverflow, который указывает на направление «компиляторы могут изобретать свои собственные правила», но все же может быть оправдание, которое я пропустил для Clang и GCC, набрав S10.z как int .

5
задан Community 23 May 2017 в 12:12
поделиться