Код работает только в том случае, если все переменные сначала установлены в 0. УБ?

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

#include <stdio.h>


int main(int argc, char *argv[])
{
   int n, reverse = 0, temp;

   printf("Enter a number to check if it is a palindrome or not\n");
   scanf("%d",&n);

   temp = n;

   while( temp != 0 )
   {
      reverse = reverse * 10;
      reverse = reverse + temp%10;
      temp = temp/10;
   }

   if ( n == reverse )
      printf("%d is a palindrome number.\n", n);
   else
      printf("%d is not a palindrome number.\n", n);

   return 0;
}

Например, приведенный выше код неправильно говорит, что «87678» не является числовым палиндромом.

Проверка возврата scanf() показывает, что это удалось, и печать значения n верна для ввода 87678.

Однако код правильно говорит, что «4554» - это палиндром.

Однако, добавив:

n = reverse = temp = 0;

до первого printf() программа все время работает корректно. Так что же происходит в первой версии? Это какое-то неопределенное поведение, когда переменные не инициализируются перед использованием?

РЕДАКТИРОВАТЬ: позже будет предоставлена ​​​​сборка скомпилированной версии, которая не видит, что делает компилятор.


person Chimera    schedule 29.10.2012    source источник
comment
Проверить возвращаемое значение scanf?   -  person Daniel Fischer    schedule 29.10.2012
comment
Была предпринята попытка отладить это, и результаты все еще были неоднозначными в отношении фактической причины такого поведения, поэтому вопрос   -  person Tony The Lion    schedule 29.10.2012
comment
почему вы передаете аргументы в main ?   -  person Code Spy    schedule 29.10.2012
comment
Пожалуйста, дайте пример ввода, для которого это не удается.   -  person Nikos C.    schedule 29.10.2012
comment
@DextOr Они не влияют на поведение этого кода.   -  person Nikos C.    schedule 29.10.2012
comment
Можете ли вы указать тест (числа), для которого он проходит только тогда, когда вы добавляете n = reverse = temp = 0; линия?   -  person sahaj    schedule 29.10.2012
comment
попробуйте напечатать temp (после scanf) в случаях, когда это не удается. Поскольку @Daniel Fischer Id ожидает, что что-то пойдет не так. Хотя в любом случае рекомендуется инициализировать переменные   -  person Thomas    schedule 29.10.2012
comment
Код в порядке, но вы должны строго проверять входные данные, переданные в scanf().   -  person Omkant    schedule 29.10.2012
comment
этот код работает - ideone.com/q7ycBU   -  person Abyx    schedule 29.10.2012
comment
На какой системе вы это запускаете?   -  person Lundin    schedule 29.10.2012
comment
Что произойдет, если вы замените строку, содержащую операцию %, на эту: reverse = reverse + (temp - 10 * (temp / 10));   -  person Nikos C.    schedule 29.10.2012
comment
Можете ли вы сообщить нам, какую версию компилятора вы используете, и, при желании, вставьте в bin вывод эквивалента gcc -S (создать сборку). У вас может быть ошибка компилятора ??   -  person dave    schedule 29.10.2012
comment
@Lundin 32-битный Linux с GCC 4.5.2 — Ubuntu 11.04. Другие отмечают, что код отлично работает в более новой версии GCC... что меня довольно удивляет.   -  person Chimera    schedule 29.10.2012
comment
Пожалуйста, покажите результат, который вы получили для 87678 (printf() переменная reverse после завершения цикла while).   -  person Nikos C.    schedule 29.10.2012
comment
Это прекрасно работает с Mingw GCC 4.6.2, а также с Embarcadero C++, протестированным на 64-битной Windows 7.   -  person Lundin    schedule 29.10.2012
comment
@NikosChantziaras после цикла значение reverse было довольно большим отрицательным числом.   -  person Chimera    schedule 29.10.2012
comment
Я полагаю, альтернативный код, который я дал 5 комментариев выше, не меняет результат?   -  person Nikos C.    schedule 29.10.2012
comment
@NikosChantziaras Не имеет значения. Спасибо за вашу помощь. Я запускаю memtest сейчас.   -  person Chimera    schedule 29.10.2012
comment
Я тоже не вижу ошибки в коде. Либо запустите его с помощью отладчика, либо добавьте несколько операторов отладки, чтобы показывать значение reverse каждый раз в цикле. Может быть, это даст ключ к разгадке.   -  person Jay    schedule 25.06.2015


Ответы (3)


Если sizeof(int) не меньше 4, вы либо столкнулись с ошибкой компилятора, ваше оборудование неисправно, либо в вашей системе происходит какая-то форма повреждения данных.

Чтобы ответить на вопрос: нет, в вашей программе нет неопределенного поведения (при условии, что scanf() действительно не выходит из строя).

Попробуйте запустить memtest в своей системе, чтобы исключить проблемы с оперативной памятью: http://www.memtest.org

person Nikos C.    schedule 29.10.2012
comment
Запускаем memtest сейчас. Спасибо, что нашли время, чтобы помочь. - person Chimera; 29.10.2012
comment
Это в значительной степени оставляет ошибку инструментальной цепочки компилятора как наиболее вероятную причину. Особенно, если он воспроизводим постоянно (аппаратный сбой обычно не дает 100% воспроизводимости). - person Nikos C.; 29.10.2012

Это очень похоже на ошибку компилятора, так как это работает с более поздними версиями gcc. Мне было бы очень интересно увидеть вывод gcc -S (пожалуйста, pastebin?), а также узнать, какую команду компиляции вы используете. (особенно уровень оптимизации).

person dave    schedule 29.10.2012
comment
Я предоставлю эту сборку, когда вернусь в офис. Спасибо. Странно, что разные компиляторы показывают разные результаты. - person Chimera; 29.10.2012

В отличие от Java, C не имеет значения по умолчанию для int. Вы можете обратиться к этому post, поскольку он обсуждает это аналогичная проблема.

person Ian    schedule 29.10.2012
comment
C имеет значения по умолчанию для переменных в зависимости от класса хранения переменной. - person Alok Save; 29.10.2012
comment
Все переменные в коде инициализируются, при условии, что scanf() не сработает. - person Nikos C.; 29.10.2012
comment
@NikosChantziaras Вот что меня озадачило. - person Chimera; 29.10.2012
comment
Да, ты прав. Предполагая, что scanf не завершается ошибкой, все эти переменные должны были быть инициализированы. Есть ли у вас ценности, которые терпят неудачу? Превышает ли оно максимальное значение int? - person Ian; 29.10.2012
comment
@IanGil Не превышать значение int. - person Chimera; 29.10.2012