Question

Ce code, lorsqu'il est compilé dans xlC 8.0 (sous AIX 5.3), produit un résultat erroné. Il faut imprimer 12345, mais imprime à la place 804399880. Retrait de la const devant result fait correctement le travail de code.

Où est le bug?

#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 commande:

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

Edit: Modification de la chaîne de format printf ci-dessus pour "% ld \ n" ne pas d'aide. Edit 2: La version AIX utilisée était 5.3, pas 6.1

.
Était-ce utile?

La solution

xlC 10.0 fonctionne très bien, semble être un bug du compilateur

Autres conseils

Ceci est étiquetée c ++, donc ce qui se passe lorsque vous utilisez Cout au lieu de printf?

Il semble que le problème est vous dire printf d'imprimer un entier non signé et envoyer un long int signé à réellement imprimer. Très probablement la mise en page de mémoire est différente et printf ne peut pas comprendre ce que vous vouliez vraiment faire.

Il va être un peu deviner pourquoi les questions de const, mais on peut faire une hypothèse raisonnable.

Variables de portée de bloc, tels que result peut être affecté à un registre ou mise sur la pile. Il existe de nombreux facteurs qui déterminent si un registre est utilisé. Il est tout à fait possible que les questions de const, dans ce cas. En fin de compte, ce sont les compilateurs droit d'utiliser ce qu'il pense qui fonctionne le mieux.

De même, les arguments des fonctions peut être transmis dans les registres ou sur la pile. Comme les fonctions sont souvent compilées séparément, leur interface (à savoir la déclaration) dicte quel argument va où. printf (...) est un cas particulier, car il peut être appelé avec des arguments différents types. En conséquence, les données finit par où variera, et vous devez dire printf (...) à quoi vous attendre.

lors du passage d'une variable à une fonction, le compilateur a généralement de le copier. D'un registre à la pile, un registre à l'autre, etc., il y a assez peu de variations possibles. Comme je l'ai indiqué, l'emplacement de la source peut varier en fonction de la présence ou l'absence de const.

Maintenant, comme il vous arrive passez le spécificateur de format erroné de printf(...), à savoir %u au lieu de %ld. Cela peut provoquer printf (...) à regarder dans le mauvais endroit pour obtenir ses données - peut-être dans un registre au lieu de la pile, ou l'inverse. Une telle action peut provoquer des résultats assez surprenants. printf(...) pourrait par exemple tomber sur votre result non copié, ou les anciennes valeurs aléatoires dans certains registre. Il semble que dans le cas non-const il arrive de trouver la valeur correcte (même si elle aurait pu trouver au mauvais endroit), alors que dans le cas const printf(...) trouve juste ordures.

Probablement pas lié, mais attention:.% U pour spécificateur printf indique un entier non signé, mais vous passez un entier signé

g ++ gère ce bien et ne fait pas mention d'avertissement. Il ne se plaint au sujet printf. Vous devez utiliser% ld pour un long int. Ou mieux encore, en utilisant% ld ou coulée à (unsigned long int).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top