Was den "was wenn es kein (unsigned) char wäre?" Fall angeht: Hier glaube ich dass es tatsächlich UB wäre. Zumindest hab' ich das öfters gelesen, u.A. auch von Leuten wo ich den Eindruck hatte dass sie wissen wovon sie reden (schreiben).
Und es macht mMn. auch Sinn. Denn wenn man sich die klassische "strict Aliasing" Problemfunktion anguckt...
int Foo(int* a, short* b)
{
*a = 0;
*b = 1;
return *a;
}
Die meisten Compiler optimieren das return *a hier (berechtigterweise) zu einem return 0 . Weil strict aliasing ja besagt dass a und b unmöglich "aliasen" können (dürfen).
Und was soll nun passieren wenn man folgendes macht
#include <stdio.h>
int Foo(int* a, short* b)
{
*a = 0;
*b = 1;
return *a;
}
union U
{
int a;
short b;
};
int main()
{
U u;
printf("Foo: %d\n", Foo(&u.a, &u.b));
}
Hier kommt mit optimiertem Code üblicherweise "Foo: 0" raus. Wenn es für enums ne Ausnahme (ohne weitere Einschränkungen) gäbe, dann müsste aber "Foo: 1" rauskommen. D.h. der Compiler dürfte in Foo nicht mehr das return *a zu return 0 optimieren. Was doof wäre, denn damit wäre die ganze strict aliasing Regel für die Katz. Was jetzt einige sicher freuen würde, aber das ist wieder ein anderes Thema -- ist halt einfach nicht so
D.h. entweder es gibt ne Ausnahme die wieder super krass eingeschränkt ist, und das Beispiel hier eben irgendwie ausschliesst, oder es ist schlichtweg einfach grundsätzlich verboten. Ich gehe wie gesagt davon aus dass es grundsätzlich verboten ist -- bzw. mehr noch, ich hoffe dass es grundsätzlich verboten ist. Weil alles andere die so schon super komplizierten Regeln in diesem Bereich noch komplizierter machen würde.