Неинициализированные значения инициализируются? - PullRequest
2 голосов
/ 04 августа 2009

В C автоматические переменные, если они не инициализированы, содержат значение мусора. Однако рассмотрим следующую программу:

int main(){
 signed char term;
 (char)term--;
 printf("%d\n",term);
}

Он печатает значение «7». Если я не делаю (char)term--, он печатает значение '8'. Таким образом, это определенно не содержит мусора. Разве это не противоречиво?

Ответы [ 7 ]

15 голосов
/ 04 августа 2009

Это фигня. Вы получаете 8 как мусор, и вычитаете, чтобы получить 7.

Вот что такое неопределенное поведение. То, что вы продолжаете получать 8, не означает, что оно четко определено. Попробуйте делать более сложные вещи в своем коде. Добавьте переменные выше и ниже вашего char.


О своем «тесте» вы говорите:

Однако, непоследовательность трудно игнорировать, учитывая, что мусор должен быть случайным.

Вы должны проверить свои предположения. «мусор должен быть случайным» говорит кто? Согласно тому, что мусор должен быть случайным? Единственный способ, которым мусор будет случайным, - это если система периодически просматривает память и присваивает ей случайные числа.

Когда мы говорим «случайно», мы имеем в виду, что не знаем, что это будет. Это не делает его недетерминированным. Это компьютеры. Если вы скажете им делать одно и то же снова и снова, он будет делать то же самое снова и снова .

Ваш компилятор и настройки продолжают генерировать один и тот же код, который в итоге дает вам эти значения мусора. Детерминированный, но вы не можете полагаться на это поведение: «случайный».

Кроме того, 1-800 не означало, что вы приняли это так, как вы. «8» не обязательно означает «мусор», так как в том, как все настроено, ваш компилятор заполняет их 8. То, что он имеет в виду, означает, что 8 так же мусор, как и любое другое число.

4 голосов
/ 04 августа 2009

Значение 8 включено в набор чисел, которые считаются «мусором» или «неинициализированным».

2 голосов
/ 04 августа 2009

Вы, кажется, перепутали термины "мусор" и "недетерминированный". Значение в термине считается мусором, потому что вы не можете контролировать, какое значение будет в нем. Оно может меняться с платформы на платформу или работать на бег, т.е. неопределенное поведение ..

С другой стороны, если все вещи в среде выполнения программы равны, значение, вероятно, будет одинаковым для каждого запуска. Это, однако, не исключает его превращения в мусор.

2 голосов
/ 04 августа 2009

Мусор с точки зрения значения - это то, что осталось в стеке какой-то предыдущей функцией. Измените libc или любое количество вещей, и это число изменится.

0 голосов
/ 04 августа 2009

Спасибо за ответы. Я опробовал небольшую модификацию:

int main(){
           signed char term1;
           signed char term2;
           signed char term3;
           printf("%d\n%d\n%d\n",term1,term2,term3);
}

Я запускал программу на 3 разных машинах. Результат был одинаковым на всех 3 машинах: term1 получает значение = -124, term2 = 4 и term3 = 8. Если я удаляю term3, term1 = 4, term2 = 8. Если я удаляю term2, term1 = 8. Так что последнее значение, которое будет декольтировано как знаковый символ, получает значение '8'. Как сказано в сообщении 1800, «8» - это одно из значений, используемых для обозначения мусора, это может быть и так. Однако непоследовательность трудно не заметить, учитывая, что мусор должен быть случайным.

0 голосов
/ 04 августа 2009

Думайте об этом как об инициализируемом произвольным значением (битовая комбинация).

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

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

0 голосов
/ 04 августа 2009

Он содержит мусор, содержит 8 бит мусора и читает двоичный код как число от 0 до 255 (притворяясь, что вы используете беззнаковый символ).

Так что память могла бы быть такой:

| 0 0 1 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 0 1 |

И он взял конец (1 0 0 1 0 1 0 1) и прочитал его как число, которое равно 149. Это зависит только от того, какой случайный двоичный файл находится в месте указанной длины (например: unsigned char = 1 байт)

Если бы это было целое число без знака, оно заняло бы 4 байта случайного мусора и превратило бы его в число.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...