Domanda

Questo codice, compilato in XLC 8.0 (su AIX 5.3), produce il risultato sbagliato. Si deve stampare 12345, ma stampa invece 804399880. Rimozione del const davanti result rende correttamente il codice di lavoro.

Dove si trova il 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;
}

comando di compilazione:

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

Modifica: Modifica della stringa di formato printf sopra per "% ld \ n" non aiuta. Edit 2: La versione di AIX usato era 5.3, non 6.1

.
È stato utile?

Soluzione

XLC 10.0 funziona bene, sembra essere un bug del compilatore

Altri suggerimenti

Si tratta di tag C ++, così che cosa succede quando si utilizza cout invece di printf?

Sembra che il problema è che stai dicendo printf per stampare un unsigned int e poi l'invio di un long int firmato per stampare in realtà. Molto probabilmente il layout di memoria è diverso e printf non riesce a capire quello che realmente voleva fare.

E 'sarà un po' di indovinare perché gli argomenti const, ma si può fare un'ipotesi ragionevole.

variabili con portata blocco, come result può essere assegnato ad un registro o messa in pila. Ci sono molti fattori che influenzano se un registro è utilizzato. E 'molto probabile che le questioni const, in questo caso. Alla fine, sono i compilatori diritto di utilizzare quello che pensa funziona meglio.

Analogamente, argomenti di funzioni può essere passata in registri o in pila. Come funzioni sono spesso compilati separatamente, la loro interfaccia (cioè dichiarazione) dettami quali argomenti si dove. printf (...) è un caso speciale, come può essere chiamato con diversi tipi di argomenti. Di conseguenza, quali sono i dati finisce dove varierà, e avete bisogno di dire a printf (...) cosa aspettarsi.

Ora, quando si passa una variabile a una funzione, il compilatore di solito per copiarlo. Da un registro alla pila, un registro all'altro, eccetera, ci sono parecchie varianti possibili. Come ho indicato, la posizione di origine può differire a seconda della presenza o assenza di const.

Ora come accade si passa l'identificatore di formato sbagliato printf(...), vale a dire %u invece di %ld. Ciò può causare printf (...) di guardare nel posto sbagliato per ottenere i suoi dati - forse in un registro al posto della pila, o viceversa. Tale azione può causare risultati abbastanza sorprendenti. printf(...) potrebbe per esempio inciampare attraverso il vostro result non copiati, oi vecchi valori casuali in alcuni registro. Sembra che, nel caso non-const capita di trovare il valore corretto (anche se potrebbe aver trovato nel posto sbagliato), mentre nel caso const printf(...) appena trova spazzatura.

Probabilmente non legato, ma fate attenzione:. La% u Prescrizione per printf indica un intero senza segno, ma si passa un intero con segno

g ++ gestisce questo bene e non menziona un avvertimento. Non si lamentano printf. Si deve usare% lu per un long int. O meglio ancora, utilizzando% ld o la fusione di (long int unsigned).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top