Frage

Der folgende Code macht keine Warnung mit G ++ 4.1.1 und -Wall.

int octalStrToInt(const std::string& s)
{    
    return strtol(s.c_str(), 0, 8);
}

Ich hatte eine Warnung erwartet, weil Strtol a zurückkehrt long int Aber meine Funktion gibt nur eine Ebene zurück int. Könnten andere Compiler hier eine Warnung abgeben? Sollte ich den Rückgabewert in diesem Fall als gute Praxis auf INT ausgeben?

War es hilfreich?

Lösung

Möglicherweise benötigen Sie die Flagge -Wconversion, um diese Warnungen einzuschalten. Es wird jedoch nicht warnen lang -> int, Da sie mit GCC gleich groß sind (der Wert ändert sich aufgrund der Umwandlung nicht). Aber wenn Sie zum Beispiel konvertieren lang -> kurz

Ich nehme an, eine Besetzung würde nicht empfohlen, da dies nur die Möglichkeit von Fehlern vertuschen würde. Es wäre in Ordnung, nachdem Sie überprüft haben, dass ein solcher Besetzung den Wert nicht ändert, um den Compiler zu beschwichtigen.

Andere Tipps

Der beste Ansatz ist:

long x = strtol(...); assert(x <= INT_MAX); return (int)x;

Du brauchst limits.h und assert.h

Wenn Sie keinen Zugriff haben boost::numeric_cast, Sie können eine einfache Nachahmung schreiben:

template <typename T, typename S>
T range_check(const S &s) {
    assert(s <= std::numeric_limits<T>::max());
    assert(s >= std::numeric_limits<T>::min());
    return static_cast<T>(s); // explicit conversion, no warnings.
}

return range_check<int>(strtol(some_value,0,8));

Eigentlich ist das ein bisschen betrügerisch, da es für schwimmende Punktzieltypen nicht funktioniert. min() Ist nicht der gleiche für sie wie für Ganzzahltypen, Sie müssen sich gegen +/-- überprüfen. max(). Übung für den Leser.

Unabhängig davon, ob Sie Assert oder ein anderes Fehlerhandling verwenden, hängt davon ab, was Sie tatsächlich für ungültige Eingaben tun möchten.

Es gibt auch boost::lexical_cast (Offhand Ich weiß nicht, wie man dieses Oktal lesen) und Stringsstream. Lesen Sie den gewünschten Typ, nicht den Typ, der eine C -Bibliotheksfunktion dafür hat.

Sie sehen hier keine Warnung, da die "int" und "langen Int" -Datenatypen auf Ihrer Plattform die gleiche Größe und denselben Bereich haben. Je nach Architektur könnten sie anders werden.

Verwenden Sie die Reichweite, um sich vor seltsamen Fehlern zu schützen. Ich empfehle Ihnen, std :: numeric_limits :: min/max (siehe) zu verwenden.

Nach der Reichweite können Sie sicher static_cast oder C-Cast verwenden.

Andererseits können Sie sich auf die gleiche Funktionen verlassen, die in der Std :: Stringstream -Klasse implementiert ist. Die Konvertierung mit STD :: Stringstream ist standardmäßig plattformfrei und vom Typ Safe.

Die meisten modernen Compiler werden abhängig von der von Ihnen konfigurierten Warnstufe vor der Konvertierung und einer möglichen Kürzung warnen. Auf msvc warn Level 4.

Die beste Praxis wäre, eine lange Aussage aus Ihrer Funktion zurückzugeben und den aufrufenden Code zu entscheiden, wie die Konvertierung behandelt wird. Abgesehen davon, dass Sie zumindest sicherstellen, dass der Wert, den Sie von Strtol zurückbekommen, in eine INT passen, bevor Sie zurückkehren, wie von let_me_be vorgeschlagen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top