Pregunta

Este código, cuando se compila en xlC 8,0 (en AIX 5.3), produce un resultado erróneo. Debe imprimir 12345, sino que imprime 804399880. Extracción de la const frente a result hace correctamente el código de trabajo.

¿Dónde está el error?

#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 de compilación:

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

Editar: Cambiar la cadena de formato printf anterior a "% ld \ n" no ayuda. Editar 2: La versión de AIX usado fue 5,3, no 6,1

.
¿Fue útil?

Solución

xlC 10,0 funciona bien, parece ser un error de compilador

Otros consejos

Este es marcada con C ++, así que lo que sucede cuando se utiliza cout en lugar de printf?

Parece que el problema es que estás diciendo printf para imprimir un entero sin signo y luego enviarlo un long int firmado a imprimir realmente. Lo más probable es el diseño de memoria es diferente y printf no puede entender lo que realmente quería hacer.

Esto va a ser un poco de una conjetura por qué los asuntos const, pero se puede hacer una suposición razonable.

Las variables con ámbito de bloque, tales como result puede ser asignado a un registro o puso en la pila. Hay muchos factores que influyen en que se utiliza un registro. Es muy posible que los asuntos const, en este caso. Al final, se trata de los compiladores derecho a usar lo que se piensa que funciona mejor.

Del mismo modo, argumentos de funciones se puede pasar en los registros o en la pila. Como funciones a menudo se compilan por separado, su interfaz (es decir Declaración) dicta qué argumento dónde. printf (...) es un caso especial, ya que puede ser llamada con diferentes tipos de argumentos. Como resultado, los datos que termina donde variará, y hay que decir printf (...) lo que puede esperar.

Ahora, cuando pasa una variable a una función, el compilador lo general tiene que copiarlo. A partir de un registro de la pila, un registro a otro, etcétera, hay un buen número de variaciones posibles. Como he indicado, la ubicación de origen puede diferir dependiendo de la presencia o ausencia de const.

Ahora bien, como sucede a pasar el especificador de formato incorrecto printf(...), es decir, en lugar de %u %ld. Esto puede causar printf (...) que debe buscar en el lugar equivocado para obtener sus datos - tal vez en un registro en lugar de la pila, o al revés. Tal acción puede causar resultados bastante sorprendentes. printf(...) podría, por ejemplo a través de su tropiezo result no copiada, o los viejos valores aleatorios en algún registro. Parece que en el caso no constante sucede para encontrar el valor correcto (a pesar de que podría haber encontrado en el lugar equivocado), mientras que en el caso const printf(...) simplemente encuentra basura.

Probablemente no relacionado, pero tenga cuidado:.% U el especificador de printf indica un entero sin signo, pero que están pasando un entero con signo

g ++ maneja esta muy bien y no menciona una advertencia. No se quejan de printf. Usted debe utilizar% lu durante mucho int. O mejor aún, el uso de% ld o fundición a (int largo sin signo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top