2014-09-02 22 views
9

Um ein wenig Hintergrund (in keinem Zusammenhang mit der Frage, die folgen) zu geben, in C++ 11 bemerkte ich eine Verengung Ausgabe:Konstante Regeln für ganzzahlige Werbung?

int foo[] = { 0xFFFFFFFF }; 

Dies versagte zu kompilieren (Umwandlung Verengung), weil 0xFFFFFFFF ein unsigned int ist . Ich habe jedoch Fälle gesehen, in denen 0xFF signiert ist.

Ich habe über Integer-Promotion-Regeln, aber dies ist meist im Kontext von lvalues ​​und nicht rvalues ​​/ Konstanten. Wie ermittelt der Compiler den Typ der Konstanten (ohne Literalsuffixe)? Gibt es eine Dokumentation oder einen netten kleinen Tisch/"Spickzettel", der die Regeln dafür zeigt? Ich bin mir nicht einmal sicher, wie das heißen soll, sonst hätte ich versucht, es selbst im C++ 11-Standard zu finden.

Vielen Dank im Voraus.

+1

Es ist der schmalste Typ benötigt mit signed priorisiert und ein Minimum von "int". – chris

+0

Ich habe meiner Antwort einige zusätzliche Details hinzugefügt, die Sie vielleicht nützlich/interessant finden. –

Antwort

12

Es gibt eine Tabelle in der Norm, die auf cppreference.com wiedergegeben wird: http://en.cppreference.com/w/cpp/language/integer_literal

Insbesondere ein hex oder Oktal Ganzzahlliteral ohne Suffix gilt als die erste Art in der folgenden Liste hat, in dem sein Wert kann dargestellt werden:

int 
unsigned int 
long int 
unsigned long int 
long long int 
unsigned long long int 

0xFFFFFFFF für int zu groß ist, wenn int 32 Bits lang ist, so unsigned int gewählt wird. Aber 0xFF passt bequem in eine int, also int ist es.

+0

So ist es sicher zu sagen, es sieht integrale Bereiche, und nicht speziell seine Bittiefe. Das hilft, die Dinge klar zu machen, wenn dem so ist. –

+0

@RobertDailey Das stimmt, ja, es hängt nicht direkt von der Anzahl der Bits ab, obwohl es offensichtlich indirekt ist. – Brian

6

Was genannt bezeichnet werden als Integer-Konstanten in C werden als Ganzzahlliterale in C++ bezeichnet. Die Regeln verwendet, um den Typ eines Ganzzahlliteral sind in den draft C++ standard2.14.2Integer Literale Abschnitt Tabelle 6 die besagt, bedeckt, um zu bestimmen:

Der Typ eines Literal ganze Zahl ist die erste von der entsprechenden Liste in Tabelle 6, in der sein Wert dargestellt werden kann.

und für Octal oder hexadezimalen Konstante ohne Suffix in der Tabelle den folgenden Auftrag hat:

int 
unsigned int 
long int 
unsigned long int 
long long int 
unsigned long long int 
kann

So 0xFF als int, während die erste Art, die dargestellt werden kann darstellen 0xFFFFFFFF wäre unsigned int.

Der Auftrag für Dezimalkonstanten ist wie folgt:

int 
long int 
long long int 

Wie wir hexadezimalen und oktalen Literale unterschiedlich verhalten sehen können, und wir können that C99 has the same table sehen. Die Rationale for International Standard—Programming Languages—C sagt der folgende dazu:

Anders als Dezimalzahl Konstanten, Oktal und Hexadezimal-Konstanten zu groß, um Ints als unsigned int eingegeben werden, wenn innerhalb der Reichweite dieser Art, da es wahrscheinlicher ist, dass sie etwas darstellen Muster oder Masken, die im Allgemeinen am besten als unsigned behandelt werden, anstatt "echte" Zahlen.

cppreference integer literal section zitiert auch Tabelle 6 im Der Typ des wörtlichen Unterabschnitt.

+2

+1 für Zitat Standard und auch mir zu sagen, wie dieses Konzept benannt ist. –

+0

im Grunde, wenn Sie vorzeichenbehaftete Ganzzahl verwenden möchten, sollten Sie einfach verwenden 'int foo [] = {-1};' – pqnet

2

0xFF ist nie negativ. Es ist eine alternative Art zu schreiben 255. (Es hat Typ int).

0xFFFFFFFF ist eine große positive Zahl. Es gibt eine Tabelle unter [lex.icon], die angibt, welcher Typ eine Integer-Konstante ist. Für Hexadezimalkonstanten ohne Suffix ist es der erste Typ in der folgenden Liste, der diese große positive Zahl enthalten kann: int, unsigned int, long int, unsigned long int, long long int, unsigned long long int. Die Implementierung könnte benutzerdefinierte Typen dieser Liste hinzufügen.

+0

@TC Ich meinte es ist nie negativ; korrigiert –