Что делают следующие объявления в C и C++?
const int * i;
int * const i;
const volatile int ip;
const int *i;
Любое из приведенных выше заявлений неверно?
Если не в чем смысл и различия между ними?
Каковы полезные применения вышеуказанных объявлений (я имею в виду, в какой ситуации мы должны использовать их в C / C++ / встроенном C)?





const int * i;
i - указатель на постоянное целое число. i можно изменить так, чтобы он указывал на другое значение, но значение, на которое указывает i, изменить нельзя.
int * const i;
i - это постоянный указатель на непостоянное целое число. Значение, на которое указывает i, можно изменить, но нельзя изменить i, чтобы указать на другое значение.
const volatile int ip;
Это довольно сложно. Тот факт, что ip - это const, означает, что компилятор не позволит вам изменить значение ip. Однако теоретически его все еще можно модифицировать, например взяв его адрес и используя оператор const_cast. Это очень опасно и не очень хорошая идея, но это разрешено. Квалификатор volatile указывает, что каждый раз, когда осуществляется доступ к ip, он всегда должен быть перезагружен из памяти, то есть НЕ должен кэшироваться в регистре. Это мешает компилятору выполнять определенные оптимизации. Вы хотите использовать квалификатор volatile, когда у вас есть переменная, которая может быть изменена другим потоком, или если вы используете ввод-вывод с отображением памяти, или в других подобных ситуациях, которые могут вызвать поведение, которого компилятор может не ожидать. Использование const и volatile для одной и той же переменной довольно необычно (но законно) - вы обычно увидите одно, но не другое.
const int *i;
Это то же самое, что и первое объявление.
Вы уверены, что volatile гарантирует, что значение, доступное только для чтения, будет отражать изменения, сделанные в другом потоке? На каких реализациях? А как насчет многоядерных архитектур с некогерентным кешем?
Если переменная - объявленconst (как здесь ip), то удаление const с помощью const_cast для изменения значения является неопределенным поведением. Кроме того, не гарантируется, что volatile сделает изменения видимыми для другого потока. Определенные компиляторы могут дать такую гарантию.
Энтони совершенно прав. volatile не делает вашу переменную зависимой от потоков. кроме того, исключение const из переменной, объявленной const, является неопределенным поведением.
volatile гарантирует следующее AFAIK, хранилища и чтения не будут переупорядочены или оптимизированы, компилятор не будет предполагать, что значение не будет изменено между ссылками на var
Несколько слов из мира микроконтроллеров: регистр (например, аналого-цифровой регистр) нередко бывает изменчивой константой. Ознакомьтесь с заголовочными файлами по умолчанию для микросхем HC11 и PIC, если у вас есть копия CodeWarrior.
const и «константа» - это разные вещи. const означает только чтение. Выражение постоянный - это выражение, которое может (а в некоторых случаях должно) вычисляться во время компиляции. Пример различия: const int r = rand();Вы читаете объявления переменных в C / C++, так сказать, справа налево.
const int *i; // pointer to a constant int (the integer value doesn't change)
int *const i; // constant pointer to an int (what i points to doesn't change)
const volatile int ip; // a constant integer whose value will never be cached by the system
У каждого из них свои цели. В любом учебнике C++ или приличном ресурсе есть объяснения по каждому из них.
Если вы собираетесь редактировать грамматику и орфографию, почему бы не ввести «Если» с «I», а не «!»?