Der folgende Code kompiliert gut sowohl mit GCC (4.2-4.6) als auch mit Clang (2.1), aber wenn ich die ausführbare Datei ausführe, gibt es mir "Bus error: 10". Ich verstehe den Grund nicht.
%Vor%Ich denke, das relevante Zitat ist:
§ 7.1.6.1 (4) von N3242:
Außer dass jedes mutable deklarierte Klassenmitglied beliebig geändert werden kann Versuch, ein konstantes Objekt während seiner Lebensdauer zu modifizieren, führt zu undefiniertes Verhalten.
Die Beispiele veranschaulichen den Punkt mit const_cast
. Wie James darauf hingewiesen hat: Das Zitat findet sich in §7.1.5 in der C ++ 03-Norm.
Eine kleine Erklärung: Diese Sprachregel erlaubt es dem Compiler, einen Nur-Lese-Speicher zu verwenden (wenn er in der Zielarchitektur verfügbar ist), wenn etwas als const
deklariert wird. Ohne diese Regel könnte const
-ness immer weggeworfen werden, ohne irgendwelche Konsequenzen fürchten zu müssen, und die Verwendung wäre nur eine Frage der Entwicklerdisziplin. So wie es ist, kann man den Leuten zumindest sagen, dass sie UB anrufen, was normalerweise eine gute Abschreckung ist. Das const_cast
selbst ist von geringer Relevanz, da es nicht darauf ankommt, wie Sie den Compiler dazu bringen, ein const
-Objekt zu manipulieren.
5.2.11.7:
Je nach Art des Objekts wird eine Schreiboperation über die Zeiger, L-Wert oder Zeiger auf den Datenmember, der sich aus einem const_cast ergibt das ein Konst-Qualifikationsmerkmal wegwirft) kann undefiniertes Verhalten erzeugen (7.1.5.1)
In Ihrem Fall versuchen Sie, Daten zu ändern, die sich im schreibgeschützten Segment befinden.
Nur weil du const weggeworfen hast, heißt das nicht, dass es dir gelingen wird, in diese Erinnerung zu schreiben.
Alles, was const_cast<T>
tut, entfernt die Const-Ness der Variablen aus der Perspektive des Compilers. Dadurch kann der Compiler Code ausgeben, um in die Variable zu schreiben. Aber zur Laufzeit, wenn der Compiler / Linker die Variable in den Nur-Lese-Speicher gebracht hat, wird die Hardware Sie daran hindern, sie zu schreiben, egal wie Sie sie umsetzen.
Ich habe keine Lösung für das eigentliche Problem. Ich kann nur sagen, nicht const_cast
verwenden, es sei denn, man möchte eine konstante Elementfunktion von einer nichtkonstanten Elementfunktion und "const_cast" das konstante Ergebnis aufrufen (um ein veränderbares Ergebnis für die nichtkonstante Elementfunktion zu erhalten) ).
Aber ich habe einen Vorschlag zur Verbesserung Ihres Designs:
%Vor% Wenn eine Variable als const
deklariert wird, darf der Compiler die Ergebnisse ausschließlich in den Nur-Lese-Speicher ausgeben. Wenn Sie einen Zeiger / Verweis auf ein const
-Objekt nehmen und dann const_cast
verwenden, um const
zu entfernen, kann dies zu einem undefinierten Verhalten führen.
Im Allgemeinen ist es sicher, const_cast
zu verwenden, wenn das Objekt, auf das verwiesen wird, nicht const
ist (selbst wenn der Zeiger / Verweis, den Sie haben, const
ist).
Das Problem ist diese Zeile:
%Vor%Weil Sie es als const deklariert haben, verursacht const_cast ein undefiniertes Verhalten - in Ihrem Fall haben Sie Glück mit einem Busfehler (es ist ein Segmentierungsfehler in meinem System).
Deklarieren Sie es nicht const, und Sie können const_cast ohne Probleme aufrufen.
Tags und Links const c++ static const-cast member