Какое значение по умолчанию для Регистра в C - PullRequest
0 голосов
/ 14 июля 2020

В C я слышал, что значение по умолчанию для спецификатора регистра - мусор. Некоторые источники говорят, что значения по умолчанию для регистра нет, поэтому могут возникнуть ошибки, если вы не инициализируете переменную с помощью спецификатора регистра. Я пробовал это Пример. Когда я выполнил код, программа показала мне значение регистра по умолчанию, равное 1. Я не знаю, какому источнику мне следует верить, и я не знаю термина «мусор». Не могли бы вы объяснить мне это? Вот код, который я выполнил:

#include <stdio.h>
int main(){
register int a;
printf("%d",a);
}

Ответы [ 4 ]

2 голосов
/ 14 июля 2020

Ключевое слово register игнорируется компиляторами, и они решают, где разместить объект. Он будет таким же не инициализированным, как автоматическая c переменная.

Некоторые компиляторы имеют расширение, позволяющее c присвоить регистр переменной. Например, g cc.

register int p1 asm ("r7");

из определенного в глобальной области видимости регистр r7 будет вынут из пула регистров и использован как переменная p1. Функции из того же модуля компиляции не будут использовать этот регистр. Другие функции могут уничтожить его).

Когда он определен в локальной области видимости, компилятор, скорее всего, оптимизирует его использование.

2 голосов
/ 14 июля 2020

register - это не что иное, как подсказка компилятору, и в настоящее время она полностью игнорируется. Применяются обычные правила инициализации POD, и в этом случае ваша переменная не будет инициализирована ничем (ie ее содержимое - это то, что в просторечии называется мусором).

1 голос
/ 14 июля 2020

Я не знаю термина «мусор».

«Мусор» - это небрежный язык. По большей части, люди подразумевают под этим следующее: «Мы не контролируем то, что есть». Это не означает, что они случайны (никто не пытается поместить туда случайные данные) или что это мусор (это не обязательно данные, не имеющие значения или значения). (Учтите, что злоумышленник, ищущий дефекты в программе, может найти неинициализированные данные, и эти данные могут фактически содержать ключи к номерам банковских счетов, паролям, криптографическим ключам или другим данным - опасно предполагать, что неинициализированные данные - это просто мусор. )

В C я слышал, что значение спецификатора Register по умолчанию - мусор.

С очень простым компилятором или некоторыми компиляторами с отключенной оптимизацией , программа может быть переведена буквально так, что для int x будет назначено некоторое пространство памяти, и использование значения x загружает данные из этой памяти, а для register int y назначается некоторый регистр, и с использованием значения y использует данные из этого регистра. Однако в современных компиляторах, использующих оптимизацию, этого обычно не происходит.

Вместо этого C исходный код представляет программу, которая выполняется на абстрактном компьютере. В абстрактной модели эта программа загружает данные, например, из памяти, назначенной x. Однако компилятор не генерирует инструкции для реализации этой программы. Компилятор анализирует программу, чтобы выяснить, как получить те же результаты, что и программа, но быстрее.

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

  • Вывод программы, включая все данные, записанные в файлы.
  • Взаимодействие ввода и вывода (поэтому запросы, записанные в стандартный вывод, должны появиться до того, как будет принят ввод , если абстрактная программа написана таким образом).
  • Доступ к volatile объектам оценивается строго в соответствии с правилами абстрактной машины.

Помимо этого, компилятор может реорганизовать программу по своему усмотрению. Когда значение x используется в выражении, компилятору не нужно загружать его из памяти, если у него уже есть копия в регистре из некоторой предыдущей работы. Или, если требуется 6*x, а у компилятора этого нет или x под рукой, но у него есть копия 3*x, то компилятор может просто взять 3*x и удвоить его вместо загрузки * 1036. * по памяти вычислить 6*x. Возможны и гораздо более сложные оптимизации.

Что произойдет, если вы никогда не инициализируете x, будь то в памяти или в регистре? Стандарт C не говорит, что происходит (с некоторыми оговорками). Это означает, что программа абстрактного компьютера не предназначена для каких-либо конкретных действий. Тогда оптимизатор в компиляторе может извлечь из этого все, что захочет. Если в выражении используется x, оптимизатору вообще не нужно загружать его из памяти, и, если x номинально назначено регистру, компилятор не должен использовать этот регистр для x. Это потому, что если x никогда не инициализировался, тогда правила стандарта C не говорят, что он имеет какое-то конкретное значение. Таким образом, не имеет значения, имеет ли память, назначенную x, содержимое 1234, но компилятор использует какой-то несвязанный регистр, который содержит 5678, потому что правила стандарта C говорят, что в памяти могло быть 5678 . Что касается компилятора, использование неконтролируемых данных из регистра аналогично использованию неконтролируемых данных из памяти, поэтому нет причин беспокоиться о фактической загрузке данных из памяти; это было бы пустой тратой времени.

Это обзор. В стандарте C есть определенные правила c о:

  • , когда значение может быть некоторым неопределенным значением, но не может быть перехвачено (генерировать исключение и завершать вашу программу или делать другие вещи),
  • когда значение может быть не только некоторым неопределенным значением, но и другим значением каждый раз, когда вы его используете,
  • при использовании неинициализированного значения может вызвать ловушку.
0 голосов
/ 15 июля 2020

C не инициализирует неявно объекты с длительностью хранения auto (т. Е. Локальными переменными или переменными блочной области), поэтому они будут содержать все, что было последним записано в этот конкретный фрагмент памяти. Это значение может быть 1, или 0, или -1234, или буквально что-нибудь еще.

Вы не должны удивляться , увидев 1 в неинициализированная переменная auto, потому что вы не должны удивляться, увидев любое значение.

Термин «мусор» - это просто сокращение от «вы не можете полагаться при любом указанном c значении ". Возможно, лучше было бы использовать термин «неопределенный».

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