wake-up-neo.net

Bedeutet "const" nur Lesezugriff oder etwas mehr?

Was bedeutet const wirklich? Schreibgeschützt scheint seine Bedeutung für mich zusammenzufassen, aber ich bin nicht sicher, ob ich recht habe.

Wenn sich schreibgeschützt und const unterscheiden, kann mir dann jemand sagen, warum?

Anlass für diese Frage war diese Antwort wobei er angibt, dass const "nur" in C schreibgeschützt bedeutet. Ich dachte, das ist allconst, unabhängig davon, ob es C oder C++ war. Was meint er?

Für eine Antwort auf die spezifischen Unterschiede in const in C vs. C++ habe ich eine neue Frage erstellt: Wie unterscheidet sich "const" in C und C++? gemäß dem Vorschlag von R. ...

29
Kim Sun-wu

Wenn Sie eine Variable als const deklarieren, geben Sie dem Compiler an, dass Sie nicht beabsichtigen, diese Variable zu ändern. Aber das bedeutet nicht, dass andere es nicht haben! Es wird lediglich eine gewisse Optimierung ermöglicht und durch einen Kompilierungsfehler benachrichtigt (Beachten Sie, dass es sich hauptsächlich um Kompilierungsfehler handelt, während const == ReadOnly Laufzeitfehler bedeuten würde).

const bedeutet nicht read only, da Sie const volatile schreiben können, dh es könnte sich jederzeit ändern, aber ich habe nicht die Absicht, es zu ändern.

BEARBEITEN: Hier ist ein klassisches Beispiel: Angenommen, ich schreibe den Code, der die aktuelle Zeit von einem speicherzugeordneten Port liest. Beachten Sie, dass RTC dem Speicher DWORD 0x1234 zugeordnet ist.

const volatile DWORD* now = (DWORD*)0x1234;

Es ist const, weil es sich um einen schreibgeschützten Port handelt, und es ist volatile, weil ich es jedes Mal, wenn ich es lese, ändert.

Beachten Sie auch, dass viele Architekturen globale Variablen effektiv als const als schreibgeschützt deklarieren, da sie von UB geändert werden müssen. In diesen Fällen manifestiert sich UB als Laufzeitfehler. In anderen Fällen wäre es eine echte UB :)

Hier ist eine gute Lektüre: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

45
ruslik

Der Compiler lässt keine Änderungen zu, die als const deklariert sind. Es ist wie du sagst.

Es wird meistens in Funktionsprototypen verwendet, um den Benutzer darüber zu informieren, dass eine Funktion dieses oder jenes nicht berührt, wenn Zeiger übergeben werden. Es funktioniert auch als eine Art Ausfallsicherheit für Sie.

7
slezica

Viele Leute sagen Ihnen, dass const bedeutet, dass Sie es nicht ändern können. Das ist offensichtlich falsch. const kann trivial weggeworfen werden. Beachten Sie diesen Ausschnitt:

void foo(const int *somevalue)
{
   int *p = (int*) somevalue;
   *p = 256;  // OMG I AM EVIL!!!!11
}

Ihr Compiler wird Sie nicht davon abhalten. Was ist also der Zweck von const? Ich würde es eher einen Vorschlag nennen. Es erinnert Sie daran, wenn Sie Funktionsprototypen des Vertrags betrachten, die Ihre Funktionen erwarten. Ihr Compiler wird Sie anschreien, wenn Sie ihn unvorsichtig brechen. (Aber nicht, wenn Sie es absichtlich brechen, wie bei dem oben genannten Cast.)

In einigen Fällen bricht der Standard absichtlich const. Beachten Sie beispielsweise die Rückgabewerte von strstr: Per Definition wird ein gewisser Versatz in den von Ihnen angegebenen const -Puffer zurückgegeben. Der zurückgegebene Wert ist jedoch nicht const. Warum? Nun, dies würde mit dem Rückgabewert von strstr in einem Nicht-const-Puffer bedeutungsvoll brechen.

2
asveikau

Zwei Byte für Byte identisch (außer für die Kommentare), minimale Fallbeispiele ... 

In C wird zuerst eine Warnung ausgegeben ...

/* Funktion, die einen Zeiger auf ein Array von 
 zwei Nur-Lese-Ganzzahlen. */
 void a (const int (* parray) [2]); 

 void b (void) 
 {
 int Array [2] = {1,2}; 
 const int crray [2] = {1,2}; 
/* C behält sich das Recht vor, dies an einem schreibgeschützten Ort zu speichern. */

 a (& Array); 
/* Warnung: Übergeben von Argument 1 von 'a' vom nicht kompatiblen Zeigertyp */
 ein (& crray); /* OK!*/
}

Nun ist dasselbe in C++ ... g ++ ist ziemlich zufrieden damit.

 // Funktion, die einen Zeiger auf ein Array 
 // von zwei Ganzzahlen verwendet, die nicht geändert werden sollen. 
 // (Wenn wir nicht die Konstante wegwerfen ;-P) 
 Void a (const int (* parray) [2]); 

 . int Array [2] = {1,2}; 
 const int crray [2] = {1,2}; 

 a (& Array); // C++ hat damit kein Problem .
 ein (& crray); // OK!
}
1
John Carter
const char * hello_1{ "Hello!" };
const char   hello_2[]{ "Hello!" };
char       * ptr{};

// take away the const-nes
// ptr = (char *)hello_1;
// *ptr = '*'; <-- write access violation
// hello_1 is in a read only memory

// take away the const-nes
ptr = (char *)hello_2;
*ptr = '*'; // <-- OK
// hello_2 is modifiable

Zeiger zeigen auf Speicher, und char * zeigt auf Speicher in dem schreibgeschützten Datensegment. Der Unterschied zwischen char * und char [] besteht darin, dass, während beide im Datensegment auf die gleiche Weise deklariert werden, char [] als lesbar behandelt wird, da es bei Verwendung auf den Stack verschoben wird.

0
user5560811