Pergunta

Este código, quando compilado em xlC 8.0 (no AIX 5.3), produz o resultado errado.Deveria imprimir 12345, mas em vez disso imprime 804399880.Removendo o const em frente de result faz o código funcionar corretamente.

Onde está o 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 de compilação:

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

Editar:Alterar a string de formato printf acima para "%ld " não ajuda.Editar 2:A versão do AIX usada foi 5.3, não 6.1.

Foi útil?

Solução

XLC 10.0 funciona bem, parece ser um bug do compilador

Outras dicas

Isso é marcado C ++, então o que acontece quando você usa o cout em vez de printf?

Parece que o problema é que você está dizendo ao PrintF para imprimir um Int não assinado e, em seguida, enviando um INT assinado muito para realmente imprimir. Provavelmente, o layout da memória é diferente e o printf não consegue entender o que você realmente queria fazer.

Será um pouco difícil adivinhar por que const é importante, mas pode-se fazer uma suposição razoável.

Variáveis ​​com escopo de bloco, como result pode ser alocado em um registrador ou colocado na pilha.Existem muitos fatores que influenciam a utilização de um registro.É bem possível que const importa, neste caso.No final das contas, o compilador está certo em usar o que acha que funciona melhor.

Da mesma forma, argumentos para funções podem ser passados ​​em registradores ou na pilha.Como as funções são frequentemente compiladas separadamente, sua interface (ou seja,declaração) determina qual argumento vai para onde.printf(...) é um caso especial, pois pode ser chamado com argumentos de diferentes tipos.Como resultado, quais dados vão parar onde irão variar, e você precisa dizer ao printf(...) o que esperar.

Agora, ao passar uma variável para uma função, o compilador geralmente precisa copiá-la.De um registro para a pilha, de um registro para outro, etc., existem algumas variações possíveis.Como indiquei, o local de origem pode diferir dependendo da presença ou ausência de const.

Agora, acontece que você passa o especificador de formato errado para printf(...), nomeadamente %u em vez de %ld.Isso pode fazer com que printf(...) procure no lugar errado para obter seus dados - talvez em um registro em vez da pilha, ou vice-versa.Tal ação pode causar resultados bastante surpreendentes. printf(...) poderia, por exemplo, tropeçar em seu não copiado result, ou os valores antigos aleatórios em algum registro.Parece que no caso não-const ele encontra o valor correto (mesmo que possa tê-lo encontrado no lugar errado), enquanto no caso const printf(...) apenas encontra lixo.

Provavelmente não está relacionado, mas tenha cuidado: o especificador %U para Printf indica um número inteiro não assinado, mas você está passando por um número inteiro assinado.

O G ++ lida com isso muito bem e não menciona um aviso. Ele reclama de printf. Você deve estar usando %Lu por um Int longo. Ou melhor ainda, usando %LD ou fundição para (não assinado Long Int).

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top