"ammessi" è l'opposto di "impedito", ma è anche il contrario di "proibito". Hai visto che la modifica del tuo oggetto const non è impedita, ma questo non significa esattamente che sia permesso.
Modifica di un oggetto const non è "consentito", nel senso di essere "permessa". Il comportamento del tuo programma non è definito dallo standard (vedi 6.7.3/5). Accade semplicemente che durante l'implementazione, in quella esecuzione, abbia visto il valore 3. In un'altra implementazione o in un altro giorno, potresti vedere un risultato diverso.
Tuttavia, non è "prevenuto", perché con il modo in cui funziona C, rilevarlo al momento della compilazione è un problema di arresto. Rilevarlo in fase di esecuzione richiede controlli aggiuntivi su tutti gli accessi alla memoria. Lo standard è progettato per non imporre un sovraccarico sulle implementazioni.
Il motivo per cui la condivisione di const è supportata, è perché se si dispone di un puntatore const su un oggetto non const, la lingua consente (in entrambi i sensi) di modificare quell'oggetto. Per fare ciò è necessario sbarazzarsi del qualificatore const. La conseguenza di ciò è che i programmatori possono anche scartare i qualificatori const dai puntatori agli oggetti che sono effettivamente const.
Ecco una (leggermente stupida) esempio di codice che scarta un qualificatore const per questo motivo:
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);
}
È stupido, perché un design migliore sarebbe quella di inoltrare-dichiarare la atom
, per rendere i puntatori ad esso completamente opaco e fornire una funzione per accedere ai dati stringati. Ma C non richiede che tu incapsuli tutto, ti permette di restituire i puntatori a tipi completamente definiti e vuole supportare questo tipo di utilizzo const per presentare una vista di sola lettura di un oggetto che è "realmente" modificabile.
fonte
2010-09-14 14:33:13
Perché C è l'incarnazione perfetta di una digitazione debole. "I tipi sono solo per divertimento, se non ti piace il tipo di qualche cosa, basta lanciarlo";) – delnan
La legge di Osborn http://www.anvari.org/fortune/Fortune_Cookies/95_osborn-s-law-variables-won- t.html – Jaydee
Perché C & C++ ti consente di fare tutto ciò che vuoi, anche se vuoi fare qualcosa di veramente, davvero stupido. –