Frage

$ 5.2.11/7 - [Hinweis: Abhängig vom Typ des Objekts eine Schreiboperation über den Zeiger, LVALUE oder Zeiger auf das Datenelement, das sich aus einem const_cast ergibt, der einen const -qualifier68 weggibt) kann und definiertes Verhalten erzeugen (7.1.5.1). ] "

Die Wortungen dieses Abschnitts (C ++ 03) sind für mich überraschend. Was überrascht ist, sind zwei Dinge.

a) Erstens die Verwendung von 'Mai'. Warum ist es "Mai"? Andere Orte im Standard sind sehr endgültig in Bezug auf das undefinierte Verhalten

b) Warum ist das Verschieben der Constness eines ursprünglich konstanten Objekts, das nicht sofort „undefiniertes Verhalten“ ist? Warum ist es so, dass ein Schreiben erforderlich ist, damit UB ausgelöst wird?

War es hilfreich?

Lösung

a) Erstens die Verwendung von 'Mai'. Warum ist es "Mai"? Andere Orte im Standard sind sehr endgültig in Bezug auf das undefinierte Verhalten

Schauen Sie nicht zu tief in die Verwendung des Wortes ein kann hier. Der Punkt ist, dass das Verschwinden von Constness in diesem Fall ein undefiniertes Verhalten verursacht.

Der C ++ - Standard verwendet "May" oder "Mai" oft, wie in:

1.3.12: undefiniertes Verhalten kann Es werden auch erwartet, wenn dieser internationale Standard die Beschreibung einer expliziten Definition von Verhalten auslässt.

Hervorhebung meiner. Grundsätzlich verwendet der Standard das Wort "Mai" wie in "wie in"darf".

b) Warum ist das Verschieben der Constness eines ursprünglich konstanten Objekts, das nicht sofort „undefiniertes Verhalten“ ist? Warum ist es so, dass ein Schreiben erforderlich ist, damit UB ausgelöst wird?

Ein Schreiben löst UB aus, da es möglich ist, dass Const-Objekte auf bestimmten Plattformen im schreibgeschützten Speicher gespeichert werden können.

Andere Tipps

Mein Verständnis ist, dass es nur UB sein wird, wenn das betreffende Objekt im Grunde genommen ein CONT -Objekt als ein Const -Zeiger oder ein Verweis auf ein Objekt ist, das ursprünglich nicht konstant war.

Die Idee ist, dass Daten, die grundsätzlich konstant sind, in einen schreibgeschützten Teil des Speichers geladen werden könnten und das Schreiben nicht funktionieren wird. Es wird jedoch garantiert ordnungsgemäß funktioniert, wenn das betreffende Objekt grundlegend veränderlich ist.

Ex:

const int  x = 4;
const int *y = x;

*const_cast<int*>(x) = 3; // UB - the pointed-to object may 
                          // be in read-only memory or whatever.

int        a = 7;
const int *b = a;

*const_cast<int*>(b) = 6; // Not UB - the pointed-to object is 
                          // fundamentally mutable.

Für einen Kommentar unten, weil Code in Kommentaren schrecklich aussieht:

In §7.1. 5.1/4 des Standards ist das angegebene Beispiel:

int i = 2;
const int * cip; // pointer to const int
cip = &i;        // OK: cv-qualified access path to unqualified
...
int* ip;
ip = const_cast <int *>( cip ); // cast needed to convert const int* to int*
*ip = 4;                        // defined: *ip points to i, a non-const object

Dies ist also ausdrücklich zulässig.

Für Ihre erste Frage, wenn etwas kann Erzeugen Sie undefiniertes Verhalten, das macht es dann nicht weniger undefiniert.

Für den zweiten Teil würde ich mir vorstellen, dass dies aus Interoperabilitätsgründen ist. Zum Beispiel hat C nicht (oder nicht, vor C99) a const Schlüsselwort. Wenn Sie also ein CONT -Objekt an eine C -Funktion übergeben möchten, müsste die Constness weggeworfen werden. Der C ++ - Standard gibt also an, dass dies zulässig ist, solange keine Schreibvorgänge durchgeführt werden. Wenn die C-Funktion nur schreibgeschützt ist, kann die Constness sicher weggegossen werden.

Auch in C ++ ist inkonsistent oder unvollständig die Konstantkorrigität weit verbreitet. Deshalb treten wir gelegentlich in Situationen ein, in denen wir Const-Ness wegwerfen müssen, um ein const-Objekt an eine Funktion zu übergeben, die sein Argument nicht ändert, es aber mit Nicht-Const übernimmt.

Ich würde glauben, das liegt daran, dass a const Objekt kann in schreibgeschütztem Speicher gespeichert werden. Das Schreiben daran kann daher viele verschiedene Effekte haben: Programmabsturz, Segmentierungsfehler oder keine Wirkung.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top