Вопрос

Этот код, когда скомпилирован в XLC 8.0 (на AIX 5.3), создает неправильный результат. Это должно распечатать 12345, но вместо печатается 804399880Отказ Удаление const спереди result Заставляет код работать правильно.

Где ошибка?

#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;
}

Команда компиляции:

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

Редактировать: Изменение строки формата Printf выше на «% ld n» не помогает. Редактировать 2: используемая версия AIX была 5,3, а не 6.1.

Это было полезно?

Решение

XLC 10.0 работает нормально, кажется, авторская ошибка компилятора

Другие советы

Это помечено C ++, так что происходит при использовании Cout вместо printf?

Похоже, что проблема в том, что вы говорите Printf напечатать unsigned int, а затем отправляя его подписанным долгом, чтобы на самом деле печатать. Скорее всего, планировка памяти отличается, и printf не может понять, что вы действительно хотели сделать.

Это будет немного догадаться, почему Const имеет значение, но можно сделать разумное предположение.

Переменные с помощью блока сферы, такие как result можно выделить в реестр или положить в стек. Есть много факторов, которые влияют на, используется ли реестр. Это вполне возможно, что const Вопросы в этом случае. В конце концов, это компиляторы правильно использовать то, что он думает, работает лучше всего.

Аналогичным образом, аргументы для функций могут быть переданы в регистры или на стеке. В качестве функций часто скомпилированы отдельно, их интерфейс (т. Е. Декларация) диктует, какой аргумент идет где. Printf (...) - это особый случай, поскольку его можно назвать с разными типами аргументов. В результате, какие данные заканчиваются, где будет варьироваться, и вам нужно сказать Printf (...) Что ожидать.

Теперь при прохождении переменной к функции компилятор обычно должен копировать его. Из реестра в стек один регистрируйся в другой, Etcetera, возможно, возможна довольно много вариаций. Как я уже указывал, местоположение источника может отличаться в зависимости от наличия или отсутствия const.

Теперь, как это происходит, вы передаете неправильный спецификатор формата printf(...), а именно %u вместо %ld. Отказ Это может привести к печати (...), чтобы посмотреть в неправильном месте, чтобы получить его данные - возможно в регистре вместо стека или наоборот. Такое действие может вызвать довольно удивительные результаты. printf(...) может, например, наткнуться на ваш неисправный result, или случайные старые значения в некоторых регистре. Похоже, что в случае, не в том случае, если это произойдет правильное значение (даже если это могло найти его в неправильном месте), тогда как в корпусе Const printf(...) просто находит мусор.

Вероятно, не связан, но будьте осторожны: спецификатор% U для printf указывает на беззнаковую целое число, но вы передаете подписанное целое число.

G ++ обрабатывает это просто хорошо и не упоминает предупреждение. Это жалуется на printf. Вы должны использовать% LU для длинного int. Или еще лучше, используя% ld или литья, чтобы (unsigned long int).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top