"Erlaubt" ist das Gegenteil von "verhindert", aber es ist auch das Gegenteil von "verboten". Sie haben gesehen, dass das Ändern Ihres const-Objekts nicht verhindert wird, aber das bedeutet nicht, dass es erlaubt ist.
Das Ändern eines const-Objekts ist nicht erlaubt im Sinne von "erlaubt". Das Verhalten Ihres Programms ist nicht durch den Standard definiert (siehe 6.7.3/5). Es ist einfach so, dass Sie bei Ihrer Implementierung auf diesem Lauf den Wert 3 gesehen haben. Bei einer anderen Implementierung oder an einem anderen Tag sehen Sie möglicherweise ein anderes Ergebnis.
Es ist jedoch nicht "verhindert", denn mit der Art und Weise, wie C-Casst funktioniert, ist das Erkennen eines Fehlers zur Kompilierungszeit ein Problem. Die Erkennung zur Laufzeit erfordert zusätzliche Prüfungen bei allen Speicherzugriffen. Der Standard wurde so konzipiert, dass Implementierungen nicht zu viel Aufwand erfordern.
Der Grund wegwerfen const wird überhaupt unterstützt, weil, wenn Sie einen Const-Zeiger auf ein nicht-const-Objekt haben, erlaubt die Sprache (in beiden Sinne), das Objekt zu ändern. Um dies zu tun, müssen Sie das const-Qualifikationsmerkmal loswerden. Die Folge davon ist, dass Programmierer const-Qualifizierer auch von Zeigern auf Objekte, die eigentlich const sind, verwerfen können.
Hier ist ein (leicht albern) Beispiel Code, der eine const-Qualifikation aus diesem Grund verwirft:
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);
}
Es ist dumm, weil ein besseres Design atom
, um zukunfts zu erklären wäre Zeiger auf es völlig undurchsichtig zu machen und bieten eine Funktion für den Zugriff auf die Stringdaten. Aber C erfordert nicht, dass Sie alles einkapseln, es ermöglicht Ihnen, Zeiger auf vollständig definierte Typen zurückzugeben, und es möchte diese Art der Verwendung von const unterstützen, um eine schreibgeschützte Ansicht eines Objekts darzustellen, das "wirklich" modifizierbar ist.
Weil C die perfekte Inkarnation der schwachen Typisierung ist. "Typen sind nur zum Spaß, wenn Sie den Typ eines Dinges nicht mögen, werfen Sie es einfach";) – delnan
Osborns Gesetz http://www.anvari.org/fortune/Fortune_Cookies/95_osborn-s-law-variables-won- t.html – Jaydee
Weil C & C++ Sie tun lassen wird, was Sie wollen, auch wenn Sie etwas wirklich, wirklich dummes tun wollen. –