Sinn von const bei Funktionen?
-
Hi, ich beschäftige mich gerade mit der korrekten Verwendung von const und lese dafür folgenden Artikel: http://www.cprogramming.com/tutorial/const_correctness.html
Dort wird unter Anderem erwähnt, dass das Definieren von const-Funktionen nur bei Methoden Sinn macht, da hiermit der implizite this-Pointer const gesetzt wird.
Aus reiner Neugier habe ich das einfach trotzdem mal bei "normalen" Funktionen ausprobiert.Folgender Code führt erwartungsgemäß zu einem Compilerfehler:
int x = 5; // globale variable void foo() const { x = 3; }
Folgender code hingegen wird problemlos übersetzt:
int x = 5; // globale variable const void foo() { x = 3; }
Das scheint aber keinen Sinn zu ergeben. Was genau ist denn hier nun const? Die globale Variable lässt sich ja problemlos ändern.
-
Stephan++ schrieb:
Das scheint aber keinen Sinn zu ergeben.
Der Schein trügt. Das void ist const, also nichts
-
Mechanics schrieb:
Stephan++ schrieb:
Das scheint aber keinen Sinn zu ergeben.
Der Schein trügt. Das void ist const, also nichts
Häääää?
Und welchen Sinn hätte dann folgendes Konstrukt?const int foo() { return 3; }
Was bringt es mir, dass der int Rückgabewert const ist?
-
Das const bezieht sich auf den Rückgabewert. Wenn der Rückgabewert ein Zeiger ist, kann man mit diesem Zeiger das Objekt nicht verändern auf das der Zeiger zeigt. Bei int oder double macht const vor der Funktion aber keinen Sinn weil die Funktion ja nur eine Zahl zurückgibt die man sowieso nicht verändern kann. Bei void macht const auch keinen Sinn.
-
Ahh, ich glaube jetzt habe ich es Verstanden.
Das folgende Konstrukt:
int x = 5; // globale variable const int* foo() { return &x; }
Hat den selben Effekt, als hätte ich einen const_cast auf x durchgeführt:
void main(void) { int* x = foo(); // Fehler, weil x nicht const const int* xc = foo(); // Klappt, da xc const }
Danke, nun bin ich etwas schlauer.
-
const int foo() { return 3; }
Ist tatsächlich effektiv equivalent zu
int foo() { return 3; }
denn jeder Funktionsaufruf würde durch §5.6 den Typ
int
haben. Der eigentliche Typ der Funktion ist natürlich im ersten Fallconst int()
, aber das macht nunmal keinen praktischen Unterschied.Falls der Rückgabetyp aber ein Klassentyp ist, macht es einen - wenn auch subtilen - Unterschied. Copy elision greift zwar, aber es kann nicht gemoved werden, falls sie nicht greift; I.e., ruft man
const std::string f();
auf, wird vom temporären Rückgabewert nicht gemoved, falls copy elision nicht angewandt wird. Von konstanten Objekten kann meistens nicht sinnvoll gemoved werden.
-
Stephan++ schrieb:
Hat den selben Effekt, als hätte ich einen const_cast auf x durchgeführt
Der const_cast ist nicht dazu da um const hinzuzufügen, sondern zu entfernen. Das hinzufügen von const passiert implizit:
int* x; const int* xc = x; // Braucht keinen cast int* y = const_cast<int*>(xc); // Kann böse Fehler verursachen. Am besten nur benutzen wenn man weiß was man tut
-
sebi707 schrieb:
Das hinzufügen von const passiert implizit:
Ach, ist das so?
http://ideone.com/TjXLqj
-
Kellerautomat schrieb:
sebi707 schrieb:
Das hinzufügen von const passiert implizit:
Ach, ist das so?
http://ideone.com/TjXLqjDass dieser Code nicht funktioniert hat einen guten Grund.
§4.4/3 schrieb:
[ Note: if a program could assign a pointer of type
T**
to a pointer of typeconst T**
(that is, if line #1 below were allowed), a program could inadvertently modify aconst
object (as it is done on line #2). For example,int main() { const char c = ’c’; char* pc; const char** pcc = &pc; // #1: not allowed *pcc = &c; *pc = ’C’; // #2: modifies a const object }
— end note ]
-
Kellerautomat schrieb:
sebi707 schrieb:
Das hinzufügen von const passiert implizit:
Ach, ist das so?
http://ideone.com/TjXLqjDas hat auch keiner behauptet, richtig wäre das so:
int main() { int x = 42; int* p = &x; int* const* q; q = &p; }
oder
int main() { int x = 42; int* p = &x; const int** q; *q = p; }
-
Man will ja den int* in einen const int* convertieren und nicht einen int** in einen const int** (die Adresse die sich hinter const int** ist ja nicht Konstant, im Falle vom Kellerautomat, würde überhaupt nichts implizit konvertiert werden müssen) ansonsten kann man sich auch das merken, was im Draf steht.