Konvertierungen in C ++ 0x einschränken. Ist es nur ich, oder klingt das wie eine bahnbrechende Veränderung?
C++0x geht um den folgenden code und ähnlichen code schlecht ausgebildet, denn es erfordert eine so genannte einschränkende Konvertierung einer double
zu einem int
.
int a[] = { 1.0 };
Frage ich mich, ob diese Art der Initialisierung ist sehr viel in der realen Welt code. Wie viele code gebrochen werden, sind von dieser änderung? Ist es viel Aufwand dies zu beheben in Ihrem code, wenn Ihr code betroffen ist?
Referenz, siehe 8.5.4/6 n3225
Eine einschränkende Konvertierung ist eine implizite Konvertierung
- von einem Gleitkomma-Typ in einen ganzzahligen Typ oder
- von long double nach double oder float, oder double zu float, außer wo die Quelle ist ein konstanter Ausdruck und dem tatsächlichen Wert nach der Konvertierung ist innerhalb des Bereichs der Werte, die dargestellt werden können (auch wenn es nicht exakt dargestellt werden), oder
- von einem integer-Typ oder ohne bereichseinschränkung enumeration-type floating-point-Typ, außer wo die Quelle ist ein konstanter Ausdruck und dem tatsächlichen Wert nach der Konvertierung passen in den target-Typ und produzieren den ursprünglichen Wert nach der Konvertierung zurück zu dem ursprünglichen Typ, oder
- von einem integer-Typ oder ohne bereichseinschränkung enumeration-Typ in einen integer-Typ, der kann nicht repräsentieren alle Werte des ursprünglichen Typs, außer wo die Quelle ist ein konstanter Ausdruck und dem tatsächlichen Wert nach der Konvertierung passen in den target-Typ und produzieren den ursprünglichen Wert nach der Konvertierung zurück zu dem ursprünglichen Typ.
InformationsquelleAutor der Frage Johannes Schaub - litb | 2010-12-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich lief in dieser Auflösung ändern, wenn ich GCC. Der compiler gedruckte Fehler, wenn Sie code wie diesen:
Glücklicherweise, die Fehlermeldungen waren einfach, und die Korrektur war einfach:
War der code in einer externen Bibliothek, mit nur zwei Ereignisse in einer Datei. Ich glaube nicht, dass das brechen änderung betrifft viel code. Neulinge könnten erhalten verwirrt, obwohl.
InformationsquelleAutor der Antwort Timothy003
Wäre ich überrascht und enttäuscht von mir zu lernen, dass keines der C++ code, den ich schrieb in den letzten 12 Jahren hatte diese Art von problem. Aber die meisten Compiler haben würde, spuckte Warnungen über irgendwelche compile-Zeit "Verengungen" alle zusammen, es sei denn, ich bin fehlt etwas.
Sind diese auch einschränkende Konvertierungen?
Wenn dem so ist, denke ich, dass Sie vielleicht ein bisschen öfter als Ihre floating-Typ integral-Typ Beispiel.
InformationsquelleAutor der Antwort aschepler
Wäre ich nicht erstaunt, dass, wenn jemand erwischt wird durch so etwas wie:
(auf meine Implementierung, die letzten beiden nicht zum gleichen Ergebnis führen, wenn Sie zurück konvertiert zu int/long, also Verengung)
Ich mich nicht erinnern, je so schreiben, obwohl. Es ist nur sinnvoll, wenn eine Annäherung an die Grenzen ist nützlich für etwas.
Dies scheint jedenfalls irgendwie plausibel zu:
aber es ist nicht völlig überzeugend, weil, wenn ich weiß, ich habe genau zwei Werte, warum setzen Sie Sie in arrays, anstatt nur
float floatval1 = val1, floatval1 = val2;
? Was ist die motivation, obwohl, warum sollte das kompilieren (und die Arbeit, vorausgesetzt, der Verlust der Präzision ist innerhalb akzeptabler Genauigkeit für das Programm), währendfloat asfloat[] = {val1, val2};
nicht? Entweder Weg, ich bin initialisieren zwei Schwimmer aus zwei ints, es ist nur so, dass in einem Fall die beiden Schwimmer geschehen zu sein, Mitglieder eines Aggregats.Scheint besonders hart in Fällen, in denen ein nicht-konstanter Ausdruck, die Ergebnisse in eine einschränkende Konvertierung, obwohl (auf eine bestimmte Implementierung), werden alle Werte des source-Typs sind darstellbar in der Ziel-Typ und Cabrio wieder auf Ihre ursprünglichen Werte:
Vorausgesetzt, es ist kein bug, vermutlich wird das Update immer um die Konvertierung zu machen explizite. Es sei denn, du tust etwas seltsam mit Makros, denke ich, dass ein array-Initialisierer wird nur angezeigt, schließen Sie den Typ des Arrays, oder zumindest auf etwas, das repräsentiert den Typ, die abhängig sein kann, auf einem template-parameter. So ein cast sollte einfach sein, wenn die ausführliche.
InformationsquelleAutor der Antwort
Einschränkende Konvertierung Fehler interagieren stark mit implizite integer-promotion-Regeln.
Hatte ich eine Fehlermeldung mit dem code, das aussah wie
Erzeugt eine einschränkende Konvertierung Fehler (was korrekt nach dem standard). Der Grund dafür ist, dass
c
undd
implizit befördert zuint
und die daraus resultierendenint
darf nicht verengt werden zurück zu char in einer Initialisierungsliste.OTOH
ist natürlich immer noch gut (sonst ist die Hölle würde losbrechen). Aber überraschend auch
ist ok und kompiliert ohne Warnung, wenn die Summe von c und d ist kleiner als CHAR_MAX. Ich denke immer noch, das ist ein Mangel in C++11, aber die Leute dort denken anders - möglicherweise, weil es nicht einfach ist zu beheben, ohne loszuwerden, entweder implizite integer-Konvertierung (das ist ein Relikt aus der Vergangenheit, als die Menschen, schrieb Sie code wie
char a=b*c/d
und erwartet, dass es zu funktionieren, auch wenn (b*c) > CHAR_MAX) oder einschränkende Konvertierung Fehler (die möglicherweise eine gute Sache).InformationsquelleAutor der Antwort Gunther Piez
Einem praktischen Beispiel, dem ich begegnet bin:
Den numerischen Literale werden implizit
double
die Ursachen, Förderung.InformationsquelleAutor der Antwort Jed
Sieht es aus wie GCC-4.7 nicht mehr gibt Fehler für einschränkende Konvertierungen, aber Warnungen statt.
InformationsquelleAutor der Antwort kyku
Versuchen Sie, hinzufügen -Wno-Verengung zu Ihren CFLAGS, zum Beispiel :
InformationsquelleAutor der Antwort Kukuh Indrayana