Каковы различия между const и volatile указателем в C? - PullRequest
10 голосов
/ 19 января 2010

Каковы различия между const и volatile-указателем в C?

Ответы [ 4 ]

16 голосов
/ 19 января 2010

Разница действительно сводится к разнице между const и volatile. Единственное, что объединяет эти два понятия, это синтаксис. const поддерживается компилятором и говорит, что «программист не может изменить это». volatile говорит, что «эти данные могут быть изменены кем-то другим», и поэтому компилятор не будет делать никаких предположений относительно этих данных. Без volatile компилятор мог бы сказать: «Я поместил эти данные из памяти в регистр, и, поскольку я ничего не сделал с этими данными, я уверен, что это то же самое, и мне не нужно считывать их в регистр снова." Когда данные помечены как volatile, компилятор не будет делать такое предположение (потому что кто-то другой мог изменить данные) и поэтому будет перечитывать данные в регистр.

Теперь, вы спрашиваете разницу между

int *const p;

и

int *volatile q;

или разница между

const int* p;

и

volatile int* q;

В первом случае: p - это указатель на int, и где эти точки указателя не могут быть изменены программистом, тогда как q - это указатель на int, и где эти точки указателя могут быть изменено кем-то кроме программиста, поэтому компилятор не делает никаких предположений об этом указателе.

Итак:

int *const p = (int*)malloc(sizeof(int));
int *volatile q = (int*)malloc(sizeof(int));
*p = 17; // legal;
p = (int*)malloc(sizoef(int)); // not legal
*q = 17; // legal;
q = (int*)malloc(sizeof(int)); // legal

В последнем случае: p - указатель на int, и то, на что указывает p, не может быть изменено программистом, тогда как q - указатель на int и что q указывает на то, что может быть изменен кем-то кроме программиста, поэтому компилятор не делает никаких предположений относительно этих данных.

int i = 17;
int j = 34;
const int *p = &i;
volatile int *q = &i;
*p = 51; // not legal
p = &j; // legal
*q = 51; // legal
q = &j; // legal
2 голосов
/ 19 января 2010

Обычно const или volatile применяется к указателю, а не к самому указателю.

const означает, что вы не можете изменять указатель через этот указатель.

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

Редактировать: обратите внимание, что даже если вам не разрешено изменять данные с помощью указателя const, данные все равно могут быть изменены другими способами. На самом деле, бывают случаи, когда вы можете иметь pointee, который одновременно const и volatile, что означает, что вы не можете его изменить, но кто-то другой может это сделать.

1 голос
/ 19 января 2010

Постоянный указатель (т. Е. const char* s = ..) указывает на данные, которые не могут быть изменены. Изменчивый указатель (т.е. volatile char* s = ...) намекает компилятору не кэшировать данные, на которые указывает указатель, в регистрах ЦП или где-либо еще. Вместо этого они перечитывают исходную ячейку памяти каждый раз, когда им это необходимо. Это необходимо, если содержимое данных может измениться вне области компилятора, например, через второй поток, модифицирующий его.

Будьте осторожны, const char* и char* const - разные вещи, то же самое для квалификатора volatile. Если вы не уверены, посмотрите их.

1 голос
/ 19 января 2010

Вот объяснение этих двух понятий

Ключевое слово const указывает, что указатель не может быть изменен после инициализации; после этого указатель защищен от модификации.

Ключевое слово volatile указывает, что значение, связанное с следующим именем, может быть изменено с помощью действий, отличных от действий в пользовательском приложении. Поэтому ключевое слово volatile полезно для объявления объектов в разделяемой памяти, к которым могут обращаться несколько процессов или областей глобальных данных, используемых для связи с процедурами обслуживания прерываний. Это происходит от здесь

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