https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107405
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> --- (In reply to Jiri Slaby from comment #4) > (In reply to Martin Liška from comment #3) > > > enum { A = 0xffffffff, B = 1 << 31, }; > > > int main() { printf("%lx %x %zu\n", A, B, sizeof(B)); } > > > > > > > Apparently, 0xffffffff is treated by the compiler as unsigned int constant > > and thus it likely leads to the promotion to a longer interger. > > The problem is that is breaks existing code (which will be barely fixed as > this is clearly gcc-13's bug (or change of behavior at least)). > > Another question is why B is affected by A at all? Also sizeof of that enum > (if one gives it a name) is 8 with gcc-13. That is not allowed by the > standard, IMO. That is how C++ behaves for years and C2X mandates such behavior too. Enumerators that don't fit into int were a GNU extensions (-pedantic-errors rejects them) and for C have been handled weirdly in the past (only specific enumerators that don't fit had wider types + the enum as whole). enum E { A = 0xdeadbeefcafebabeULL, B = 2 }; int a = sizeof (enum E); int b = sizeof (A); int c = sizeof (B); above yielded a = 8, b = 8, c = 4 in C, a = b = c = 8 in C++ and now in GCC 13 in C too. See https://gcc.gnu.org/pipermail/gcc-patches/2022-October/603809.html for more details.