it-roy-ru.com

"Const" означает "только для чтения" или что-то еще?

Что на самом деле означает const? Похоже, что только чтение доступно для меня, но я не уверен, что прав.

Если только для чтения и const разные, кто-то может сказать мне, почему?

Этот вопрос вызвал то, что этот ответ где он заявляет, что const "просто" означает только для чтения на C. Я думал, что это означает allconst, независимо от того, был ли это C или C++. Что он имеет в виду?

Для ответа на конкретные различия в const в C против C++ я создал новый вопрос: Как «const» отличается в C и C++? согласно предложению Р. ..

29
Kim Sun-wu

Объявляя переменную как const, вы указываете компилятору, что у вас нет намерений изменять эту переменную. Но это не значит, что другие не имеют! Это просто для некоторой оптимизации и уведомления об ошибке компиляции (обратите внимание, что это в основном ошибка компиляции, тогда как const == ReadOnly будет означать ошибки времени выполнения).

const не означает read only, потому что вы можете написать const volatile, что будет означать он может измениться сам в любое время, но я не собираюсь его изменять.

Правка: вот классический пример: представьте, что я пишу код, который читает текущее время из отображенного в памяти порта. Учтите, что RTC сопоставлен с памятью DWORD 0x1234.

const volatile DWORD* now = (DWORD*)0x1234;

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

Также обратите внимание, что многие архитектуры эффективно делают глобальные переменные, объявленные как const только для чтения, потому что это UB, чтобы изменить их. В этих случаях UB будет проявляться как ошибка времени выполнения. В других случаях это был бы настоящий UB :)

Вот хорошее чтение: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

45
ruslik

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

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

7
slezica

Многие люди говорят вам, что const означает, что вы не можете изменить его. То есть явно ложный, const может быть тривиально отброшен. Обратите внимание на этот фрагмент:

void foo(const int *somevalue)
{
   int *p = (int*) somevalue;
   *p = 256;  // OMG I AM EVIL!!!!11
}

Ваш компилятор не остановит вас от этого. Итак, какова же цель const? Я бы назвал это скорее предложением. Это напоминает вам, когда вы смотрите на прототипы функций контракта, которые ожидают ваши функции. Ваш компилятор будет кричать на вас, если вы небрежно сломаете его. (Но не в том случае, если вы намеренно сломаете его, как в приведенном выше примере.)

В некоторых случаях стандарт намеренно нарушает const. Обратите внимание на возвращаемые значения strstr, например: по определению он вернет некоторое смещение в предоставленный вами буфер const ... Но возвращаемое значение не является const. Зачем? Что ж, это могло бы привести к значительному разрыву при использовании возвращаемого значения strstr в буфере, отличном от -const.

2
asveikau

Два байта для байта идентичны (за исключением комментариев) минимальными примерами ... 

Сначала в C, gcc выдаст предупреждение ...

/* Функция, принимающая указатель на массив 
 два целых числа только для чтения. */
 void a (const int (* parray) [2]); 

 void b (void) 
 {
 int array [2] = {1,2}; 
 const int crray [2] = {1,2}; 
/* C оставляет за собой право хранить его в доступном только для чтения месте. */

 а (& массив); 
/* предупреждение: передача аргумента 1 из «a» из несовместимого типа указателя */
 (& crray); /* ХОРОШО!*/
}

Теперь то же самое в C++ ... g ++ вполне доволен этим.

 // Функция получает указатель на массив 
 // из двух целых чисел, который обещает не изменять. 
 // (Если мы не отбрасываем его константу ;-P) 
 Void a (const int (* parray) [2]); 

 Void b (void) 
 {.__ , int array [2] = {1,2}; 
 const int crray [2] = {1,2}; 

 а (& массив); // C++ не имеет проблем с этим .
 (& crray); // ХОРОШО!
}
1
John Carter
const char * hello_1{ "Hello!" };
const char   hello_2[]{ "Hello!" };
char       * ptr{};

// take away the const-nes
// ptr = (char *)hello_1;
// *ptr = '*'; <-- write access violation
// hello_1 is in a read only memory

// take away the const-nes
ptr = (char *)hello_2;
*ptr = '*'; // <-- OK
// hello_2 is modifiable

Указатели указывают на память, а char * указывает на память в сегменте данных, который доступен только для чтения. Разница между char * и char [] состоит в том, что, хотя оба они объявляются одинаково в сегменте данных, char [] рассматривается как читаемый, потому что он помещается в стек, если он используется.

0
user5560811