2015-07-01 7 views
21

Ich habe den folgenden Code.Warum generiert 'typeof enum constant' eine Warnung im Vergleich zu einer Variablen vom Typ enum?

typedef enum {FOO, BAR} Baz; 

int main() 
{ 
    Baz f1 = FOO; 
    typeof(FOO) f2 = FOO; 
    return (f1 == f2); 
} 

Meine Kompilation gcc -Wextra foo.c mit einer Warnung sagen

foo.c: In function ‘main’: 
foo.c:7:13: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] 
return (f1 == f2); 
      ^

Meine gcc Version

gcc --version 
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2 

Wie kann ich dieses Problem beheben?

+1

http: // Stapelüberlauf.com/questions/10582523/how-are-integer-types-implizit konvertiert (falsches Duplikat, da die akzeptierte Antwort falsch ist) – Lundin

+3

Es ist erwähnenswert, dass 'typeof' eine Gcc-spezifische Erweiterung ist. –

Antwort

20

§6.7.2.2, direkt von C11 Kapiteln Zitiert Enumeration Spezifizierer,

Jeder Aufzählungstyp wird mit char ein vorzeichenbehaftete Ganzzahl-Typ oder ein Integer-Typ unsigned kompatibel sein. Die Wahl des Typs ist implementierungsdefiniert.

Also, der Typ des Enum-Variable wird nicht von Standard definiert. Es kann einer der oben genannten sein.

OTOH, FOO eine Aufzählung Konstante ist, wird typeof(FOO) geben Sie int, wie die Standard-Mandate

Ein erklärt Kennung als eine Aufzählung Konstante Typ int hat.

, die als Typ für f2 verwendet wird. Jetzt

, wenn Enum unsigned int auf Ihre Implementierung ist, ist so f1 und f2 ist int.

Als nächstes erhalten Sie die Warnung.

Wie kann ich dieses Problem beheben?

Nun, wenn Sie die Art der f2 zu typeof(Baz) ändern, die den Typ der Enumeration gibt, dann die beiden Typen von f1 und f2 gleich sein wird. Compiler wird glücklich sein.

SEE LIVE HERE

+0

Ich habe ein kleines Update gemacht. Der Aufzählungstyp kann mit "char" oder mit * any * vorzeichenbehafteten oder vorzeichenlosen Integer-Typen kompatibel sein. –

16

Es ist ein bekannter "Bug" in dem C-Standard. Die Enumeration Konstanten sind garantiert vom Typ int, während die Enumeration Variablen vom implementation-defined Integer-Typ sind.

See this für Referenzen.

+0

Warum haben sie das getan, anstatt nur die normalen Promotionsregeln zuzulassen (d. H. Sie können jeden Typ haben, der zu int hochlädt)? – Random832

+0

@ Random832 Kein Grund wurde jemals in C90 oder späteren Standards gegeben. Ich nehme an, sie würden gerne Speicher sparen, indem sie Enums in Bytegröße zulassen, und theoretisch wäre es in vielen Fällen praktisch, ein Ein-Byte-Enum zu haben. In der Praxis können Sie jedoch niemals Code schreiben, der darauf angewiesen ist, da dieser Code nicht portierbar wäre. Dies ist nur einer von vielen wirklich dummen Dingen im C-Standard, wie zum Beispiel die verschiedenen impliziten Typ-Promotion-Regeln. – Lundin

+0

Ja, aber ein Byte kann zu einem int fördern. In der Praxis würde FOO in fast jedem Ausdruck immer noch wie ein Int wirken, selbst wenn sein Typ tatsächlich der des Enums entspricht. – Random832

Verwandte Themen