GCC: Der Vergleich ist aufgrund des begrenzten Bereichs des Datentyps immer wahr - in Template Parameter?

8

Ich möchte eine Vorlage schreiben, die mir den kleinsten vorzeichenbehafteten ganzzahligen Typ zurückgibt, der eine gegebene Zahl darstellen kann. Das ist meine Lösung:

%Vor%

Allerdings akzeptiert GCC diesen Code nicht. Ich erhalte eine Fehlermeldung "Der Vergleich ist immer wahr wegen des begrenzten Bereichs des Datentyps [-Werror = type-limits]". Warum passiert das? n ist eine vorzeichenbehaftete 64-Bit-Ganzzahl, und alle Vergleiche können für verschiedene Werte von n wahr oder falsch sein, oder übersehe ich etwas?

Ich werde mich für jede Hilfe freuen.

Edit: Ich sollte erwähnen, dass ich C ++ 11 verwende.

    
Benjamin Schug 03.05.2012, 15:34
quelle

5 Antworten

4

Es ist ein Problem mit gcc, Warnungen im Vorlagencode können frustrierend sein. Sie können entweder die Warnung ändern oder einen anderen Ansatz verwenden.

Wie Sie vielleicht wissen, wird Vorlagencode zweimal analysiert:

  • einmal beim ersten Auffinden (Parsen)
  • einmal bei der Instanziierung für einen bestimmten Typ / Wert

Das Problem hier ist, dass bei der Instanziierung die Überprüfung trivial ist (ja 65 passt in ein int Danke), und der Compiler erkennt nicht, dass diese Warnung nicht für alle Instanzen gilt :( Es ist sehr frustrierend in der Tat für diejenigen von uns, die nach einer warnungsfreien Kompilier-Erfahrung mit Warnungen auf streben.

Sie haben 3 Möglichkeiten:

  • Deaktivieren Sie diese Warnung oder reduzieren Sie sie auf einen Nicht-Fehler
  • Verwenden Sie ein Pragma, um es selektiv für diesen Code zu deaktivieren
  • überarbeiten den Code in einem anderen Format, so dass er die Warnung nicht mehr auslöst

Beachten Sie, dass manchmal die dritte Möglichkeit eine massive Änderung und eine viel kompliziertere Lösung beinhaltet. Ich rate vom komplizierten Code nur ab, um ahnungslose Warnungen loszuwerden.

BEARBEITEN :

Eine mögliche Problemumgehung:

%Vor%

... durch Ändern der Art der im Vergleich verwendeten Daten sollte die Warnung des Compilers stummgeschaltet werden. Ich vermute explizites Casting ( int64_t(std::numeric_limits<int8_t>::max()) ) könnte auch funktionieren, aber ich fand das besser lesbar.

    
Matthieu M. 03.05.2012, 15:54
quelle
2

Der Fehler tritt auf, weil Sie GCC gebeten haben, Ihnen mit -Werror=type-limits Fehler bezüglich dieser Warnung mitzuteilen. Die Warnung -Wtype-limits gibt eine Warnung aus, wenn Sie jemals einen Vergleich durchführen, der aufgrund der Bereiche der angegebenen Datentypen immer wahr ist, zum Beispiel:

%Vor%

Diese Warnung kann manchmal nützlich sein, aber in vielen Fällen einschließlich dieser ist es nur nutzlose Pedanterie und kann ignoriert werden. Es ist normalerweise eine Warnung (aktiviert als Teil von -Wextra , wenn Sie das verwenden), aber mit -Werror oder -Werror=type-limits macht GCC einen Fehler.

Da es sich in diesem Fall nicht wirklich um ein potenzielles Problem mit Ihrem Code handelt, schalten Sie einfach die Warnung mit -Wno-type-limits aus oder machen Sie keinen Fehler mit Werror=no-type-limits , wenn es Ihnen nichts ausmacht, diese Warnungen zu sehen die Compiler-Ausgabe.

    
Adam Rosenfield 03.05.2012 15:45
quelle
1
%Vor%

Das ist in C ++ nicht möglich (in C ++ 11 können Sie) - numeric_limits<int8_t>::max() ist keine Zeitkonstante für die Kompilierung. Verwenden Sie C ++ 11?

BTW, Boost bietet Ihnen dies bereits: Ссылка

    
Anycorn 03.05.2012 15:42
quelle
1

Ich denke, die anderen Antworten auf das Problem sind falsch. Ich glaube nicht, dass dies ein Fall eines übereifrigen Compilers ist, aber ich glaube, es ist ein Compiler-Bug. Dieser Code löst weiterhin die Warnung aus:

%Vor%

Beim Aufruf von a<500>(); , aber dieser Code nicht:

%Vor%

std :: numeric_limits :: max () ergibt 127. Ich werde später einen Bugzilla-Bericht für diesen Tag ablegen, wenn niemand anders tut.

    
David Stone 03.05.2012 16:24
quelle
0

Sie erhalten die Warnung, weil einige Vergleiche für einige Instanzen von template <int64_t n> struct IntTypeThatFits mit kleinen n (kleiner als 2 ^ 32) immer wahr sind (sic!), weil der Operand während des Kompilierens reicht Zeit .

Dies könnte in diesem Fall als eine gefälschte Warnung angesehen werden, da Ihr Code davon abhängt, OTOH Sie explizit aufgefordert haben, es zu einem Fehler mit einem -Werror oder einem ähnlichen Befehlszeilenschalter zu machen / p>     

hirschhornsalz 03.05.2012 15:48
quelle

Tags und Links