2015-02-27 12 views
3

В C, могу ли я получить доступ к автоматической переменной volatile без необходимости ее инициализации в первую очередь или всегда приводит к неопределенному поведению?Можно ли безопасно прочитать неинициализированную автоматическую изменчивую переменную в C?

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

+5

* Как * объявлены переменные? Используется ли какое-либо расширение компилятора для отображения? Или вы используете указатели? –

+5

Если аппаратные регистры сопоставляются с переменными, то я очень сомневаюсь, что эти переменные будут иметь автоматическую продолжительность хранения. Таким образом, этот вопрос не имеет смысла. Просьба привести пример кода того, что вы имеете в виду. – user694733

+1

Переменная 'volatile', отображаемая на аппаратное устройство, не будет' automatic'. –

ответ

6

Автоматическая переменная, как правило, находится на call stack (но это специфичная для реализации), поэтому обычно это не будет какое-то конкретное аппаратное «устройство» (если только указатель стека не является мусором). Если это так (в стеке), переменная наследуется от предыдущего содержимого этого расположения стека. Если летучие например, как в

void foo(void) { 
    volatile int x; 
    // here x contains garbage 
} 

доступа, что x дает некоторое «неопределенное значение», и что доступ является неопределенным поведением.

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

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

+0

Часто аппаратные регистры представлены как указатели на 'volatile', и эти * указатели * могут, конечно, быть автоматическими. Возможно, это путает ОП. – unwind

+2

@unwind Объявление указателя, например, например, 'volatile int * ptr;' не делает переменную _pointer переменной volatile. Он по-прежнему является простой переменной автоматического хранения (с учетом того, что он был объявлен в локальной области).Чтобы сделать фактический указатель изменчивым, вам нужно написать что-то неясное, например 'int * volatile ptr;'. Почему бы кто-то этого не хотел, я понятия не имею. – Lundin

+0

@ Lundin Uh, да, это именно то, что я сказал ... или, по крайней мере, то, что я хотел сказать. Указатель может быть автоматическим, указывая на изменчивые данные, но это не означает, что автоматическая вещь также является изменчивой. – unwind

1

Доступ к значению неинициализированной переменной (или местоположения памяти) приведет к неопределенному поведению в отношении стандарта C. Это означает, что стандарт C не говорит, что произойдет.

Существуют и другие источники, которые могут определять, что произойдет в определенных случаях. В случае летучих переменных определение того, что происходит, почти всегда зависит от платформы.

Поэтому вам нужно проконсультироваться с соответствующей документацией для данной переменной.

0

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

В стандарте C++ 11 указывается, что энергозависимый не должен использоваться для ввода/вывода без аппаратной памяти. Используйте атомный или один из типов синхронизации (событие, мьютекс, семафор, ...), чтобы предоставить Memory Barrier по мере необходимости.

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

Смежные вопросы