Frage

Dieser Code, wenn in xlC 8.0 (auf AIX 5.3) erstellt, erzeugt das falsche Ergebnis. Es sollte 12345 drucken, sondern druckt 804399880. Das Entfernen des const vor result macht den Code richtig funktioniert.

Wo ist der Fehler?

#include <stdio.h>
#include <stdlib.h>
#include <string>

long int foo(std::string input)
{
        return strtol(input.c_str(), NULL, 0);
}

void bar()
{
        const long int result = foo("12345");
        printf("%u\n", result);
}

int
main()
{
        bar();
        return 0;
}

Compilation-Befehl:

/usr/vacpp/bin/xlC example.cpp -g

Edit: Ändern des Printf oben auf "% ld \ n" nicht hilft. Edit 2: Die AIX-Version verwendet wurde, 5.3, 6.1 nicht

.
War es hilfreich?

Lösung

xlC 10.0 funktioniert gut, scheint ein Compiler Fehler zu sein

Andere Tipps

Dies ist getaggten c ++, so was passiert, wenn Sie cout statt printf verwenden?

Es sieht aus wie das Problem ist, dass Sie printf doch sagen, eine unsigned int zu drucken und dann ein unterzeichnetes long int tatsächlich drucken senden. Höchstwahrscheinlich wird das Speicher-Layout ist anders und printf kann nicht verstehen, was Sie wollten eigentlich tun.

Es wird ein bisschen eine Vermutung, warum die const Angelegenheiten, aber man kann eine vernünftige Annahme machen.

Variablen mit Block Umfang, wie result kann auf dem Stapel zu einem Register oder setzt zugeordnet werden. Es gibt viele Faktoren, die Einfluss darauf, ob ein Register verwendet wird. Es ist durchaus möglich, dass const Angelegenheiten, in diesem Fall. Am Ende ist es die Compiler richtig zu verwenden, was es denkt, am besten funktioniert.

Ebenso Argumente an Funktionen können in den Registern oder auf dem Stack übergeben werden. Als Funktionen oft separat kompiliert sind, deren Grenzfläche (das heißt Deklaration) diktiert, welches Argument geht, wo. printf (...) ist ein Sonderfall, da es mit verschiedenen Arten Argumenten aufgerufen werden kann. Als Ergebnis endet, welche Daten wo variieren, und Sie müssen printf sagen, (...), was zu erwarten ist.

Nun, wenn eine Variable an eine Funktion übergeben, hat der Compiler in der Regel um es zu kopieren. Von einem Register auf den Stapel, registrieren Sie einem zum anderen, und so weiter, gibt es ziemlich viele Variationen möglich. Wie ich erwähnte, kann der Quellenort unterscheidet sich in Abhängigkeit von der Anwesenheit oder Abwesenheit von const.

Nun, wie es geschieht Sie die falsche Formatangabe zu printf(...) passieren, nämlich statt %u %ld. Dies kann dazu führen printf (...) an der falschen Stelle zu suchen, seine Daten zu bekommen - vielleicht in einem Register anstelle dem Stapel, oder umgekehrt. Eine solche Aktion kann durchaus überraschenden Ergebnissen führen. printf(...) könnte zum Beispiel Stolpern über Ihre nicht kopieren result oder die zufälligen alten Werte in einem gewissen Register. Es scheint, dass in dem nicht konstanten Fall es den richtigen Wert finden passiert (auch wenn es sie an der falschen Stelle gefunden haben könnte), während im konst Fall printf(...) findet nur Müll.

Wahrscheinlich nicht verwandt, aber Vorsicht:. Das% u für printf Spezifizierer eine Integer ohne Vorzeichen zeigt an, aber Sie übergeben eine signierte ganze Zahl

g ++ behandelt diese ganz gut und erwähnt nicht eine Warnung aus. Es beschwert sich über printf. Sie sollten für eine lange int verwenden% lu sein. Oder noch besser, mit% ld oder Gießen (unsigned long int).

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