«Разрешено» является противостоящим «предотвращено», но это также противоположность «запрещенному». Вы видели, что изменение вашего объекта const не предотвращается, но это не означает, что это разрешено.
Изменение объекта const не допускается «в разрешении». Поведение вашей программы не определяется стандартом (см. 6.7.3/5). Просто случается так, что при реализации в этом запуске вы видите значение 3. В другой реализации или в другой день вы можете увидеть другой результат.
Однако, это не «предотвращено», потому что с тем, как работает C cast, обнаружение его во время компиляции является проблемой остановки. Обнаружение этого во время выполнения требует дополнительных проверок во всех обращениях к памяти. Стандарт разработан, чтобы не налагать много накладных расходов на реализации.
Причина отказа от const поддерживается вообще, потому что, если у вас есть указатель const на неконстантный объект, этот язык позволяет вам (в обоих смыслах) изменять этот объект. Для этого вам нужно избавиться от спецификатора const. Следствием этого является то, что программисты могут также отбрасывать квалификаторы const от указателей на объекты, которые фактически являются константами.
Вот (слегка глупый) пример кода, который отбрасывает константный спецификатор по этой причине:
typedef struct {
const char *stringdata;
int refcount;
} atom;
// returns const, because clients aren't allowed to directly modify atoms,
// just read them
const atom *getAtom(const char *s) {
atom *a = lookup_in_global_collection_of_atoms(s);
if (a == 0) {
// error-handling omitted
atom *a = malloc(sizeof(atom));
a->stringdata = strdup(s);
a->refcount = 1;
insert_in_global_collection_of_atoms(a);
} else {
a->refcount++;
}
return a;
}
// takes const, because that's what the client has
void derefAtom(const atom *a) {
atom *tmp = (atom*)a;
--(tmp->refcount);
if (tmp->refcount == 0) {
remove_from_global_collection_of_atoms(a);
free(atom->stringdata);
free(atom);
}
}
void refAtom(const atom *a) {
++(((atom*) a)->refcount);
}
Это глупо, потому что лучше дизайн будет пересылать-объявить atom
, чтобы сделать указатели на это полностью непрозрачный , и предоставить функцию для доступа к строковым данным. Но C не требует, чтобы вы инкапсулировали все, он позволяет вам возвращать указатели на полностью определенные типы и хочет поддерживать этот тип использования const, чтобы представить просмотр только для объекта, который «действительно» модифицируется.
Потому что C - идеальное воплощение слабого набора текста. «Типы просто для удовольствия, если вам не нравится какой-то тип, просто бросьте его»;) – delnan
Закон Осборна http://www.anvari.org/fortune/Fortune_Cookies/95_osborn-s-law-variables-won- t.html – Jaydee
Потому что C & C++ позволит вам делать все, что угодно, даже если вы хотите сделать что-то действительно, действительно глупо. –