wieso Konstanten mit "const" erzeugen ?
-
jop.
const float f=3.14; const float *pcf = &f; float *pvf = const_cast<float*>(pcf) *pvf = 1.41müsste funktioniern
/edit: argl. bin zu lahm heute.
-
Mit const sollte man aufpassen (abgesehen davon, dass man von Literalen das const nicht entfernen darf). Dieser Code ist ist kein legales C++:
int a = 10; { const int& b = a; a = 5; // verboten solange b lebt! }
-
kann man überhaupt eine const reference auf eine non-const variable beziehen?
-
ja klar. macht man sogar häufig. aber ich verstehe 7H3 N4C3Rs code trotzdem nicht

geloescht
-
Also was hier wieder fuer ne kriminelle energie zu tage kommt

Schaut euch mal an, wo euer compiler die const und nichtconst Variablen ablegt ...
int Testfunktion() { int test1 = 0; const int test2 = 5; }wenn ihr nen einigermasen vernuenftigen compiler habt, wird test2 immer an der selben speichgeradresse stehen, egal wo und wie die funktion aufgerufen wird ... und sie wird hoechstwahrscheinlich auch im constanten speicherbereich abgelegt werden ...
bei
const int test2 = test1;
sieht die sache wieder etwas anders aus ...
dort nutzt man das const wirklich nur, um vor sich selbst / vor den usern zu schuetzen ....
wenn man bibliotheken schreibt wird man es lieben lernen, sonst klingelt eh aller 5 min das telefon wegens nachfragen ... weil fehler auftreten die man nie vorraussehen kann, da ist das const extenziell wichtig ...Ciao ...
-
pumuckl schrieb:
kann man überhaupt eine const reference auf eine non-const variable beziehen?
Strenggenommen gibt es keine const reference. Eine Referenz ist per Definition const in dem Sinne, dass sie einmal gebunden, nicht verändert werden kann. Eine Referenz-auf-const kann aber natürlich problemlos an eine nicht-konstante Variable gebunden werden.
Eure Beispiele mit den const_casts erzeugen übrigens alle undefiniertes Verhalten und funktionieren somit nicht. Dem Compiler das Maul zu verbieten ist nicht äquivalent zu "funktioniert".
7H3 N4C3R schrieb:
Dieser Code ist ist kein legales C++:
int a = 10; { const int& b = a; a = 5; // verboten solange b lebt! }Das wäre mir neu. Chapter und Verse, bitte.
Imo ist das einfach nur ein typisches Beispiel für aliasing und zeigt den Unterschied zwischen einer Referenz-auf-const und einer Konstanten. Ersteres heißt nur, dass du über die Referenz (oder den Zeiger) das referenzierte Objekt nicht ändern darfst. Es heißt aber nicht, dass sich das referenzierte Objekt garantiert nicht ändert.
-
7H3 N4C3R schrieb:
otze schrieb:
Auch kann der compiler mit einer konstanten variable viele lustige sachen machen, zb vorberechnen oder rausoptimieren.
Kann man so nicht ganz pauschal sagen. Was Du wahrscheinlich meinst, kann und macht er auch ohne const. Aliasing ist das größte Problem dabei, wo auch kein const weiterhilft.
nur mit const kann der compiler es einfacher machen, zumindest bei pod typen, denn da sieht er, dass die ganze variable nicht mehr geändert werden _kann_(zb durch mutable/volatile), und kann viel einfacher damit arbeiten
-
HumeSikkins schrieb:
Das wäre mir neu. Chapter und Verse, bitte.
Hmm... da erwischt du mich auf dem falschen Fuß. Ich habe momentan keine Ahnung, wo ich das herhatte, ich glaube aber aus dem Standard oder eines von Sutters Büchern. Von daher habe ich dieser Behauptung auch geglaubt. Ich meine, das damit zutun, dass es eine const T& ist. Für diese kann eine temporäre Variable angelegt werden, sofern T nicht const oder vom Typ T ist. Ändert man nun das a in meinem Beispiel, so wäre die temporäre Variable, die b referenziert, nicht mehr synchron mit der eigentlichen.
Besser verständlich, macht es wohl dieses Beispiel. Ich würde jetzt nicht meine Hand ins Feuer legen, dass mein letztes 100% richtig ist, da mir die Quelle fehlt.
int i = 5; const double& d = i; // ist okay, es wird ein temporärer double angelegt, der solange lebt wie d i = 6; // was nun?Das steht auf jeden Fall im Struppi beschrieben im Kapitel 5.5 (Seite 106 in der 3. Auflage).
-
7H3 N4C3R schrieb:
HumeSikkins schrieb:
Das wäre mir neu. Chapter und Verse, bitte.
Hmm... da erwischt du mich auf dem falschen Fuß. Ich habe momentan keine Ahnung, wo ich das herhatte, ich glaube aber aus dem Standard oder eines von Sutters Büchern. Von daher habe ich dieser Behauptung auch geglaubt. Ich meine, das damit zutun, dass es eine const T& ist. Für diese kann eine temporäre Variable angelegt werden, sofern T nicht const oder vom Typ T ist. Ändert man nun das a in meinem Beispiel, so wäre die temporäre Variable, die b referenziert, nicht mehr synchron mit der eigentlichen.
Besser verständlich, macht es wohl dieses Beispiel. Ich würde jetzt nicht meine Hand ins Feuer legen, dass mein letztes 100% richtig ist, da mir die Quelle fehlt.
int i = 5; const double& d = i; // ist okay, es wird ein temporärer double angelegt, der solange lebt wie d i = 6; // was nun?Das steht auf jeden Fall im Struppi beschrieben im Kapitel 5.5 (Seite 106 in der 3. Auflage).
Lies dir das nochmal durch... ein temporary wird nur erzeugt, wenn eine referenz auf const an ein rvalue gebunden werden soll. in diesem falle lebt das temporary solange wir die referenz. In obigem beispiel ist i bei der initialisierung aber ein lvalue, und es wird kein temporary erzeugt, i und d sind völlig syncron, d ist nur ein alias. wenn i geändert wird, ändert sich auch d. const ist immer nur einschränkung bezüglich dessen, was man mit einem objekt machen kann. es bedeutet nicht zwingend, dass sich das objekt nicht ändert - diese garantie kann nur gegeben werden, falls das objekt nirgendwo im system einen non-const namen hat.
-
Der Typ ist aber unterschiedlich, wodurch auch ein Temporary erzeugt wird (solange eine geeignete Konvertierung existiert). Wie sollte es sonst auch gehen, int und double sind (zumindest in 99%) auch nicht binär kompatibel. Kann man in 5 Minuten auch selbst ausprobieren.
#include <iostream> using namespace std; int main () { int i = 5; const double& d = i; cout << i << " " << d << endl; ++i; cout << i << " " << d << endl; }Ausgabe unter g++:
5 5
6 5Was aber aufgrund der Referenz semantischer Unfug ist. Das würde zumindest stützen, dass das nicht definiertes Verhalten ist. Für Gegenbeispiele bin ich aber gerne offen.
-
ups, gar nicht gesehen, dass i und d unterscheidlichen typ haben

dann ist nat. alles klar. ein lvalue kann nat. nur an eine (ggf. const-qualifizierte) referenz gleichen typs gebunden werden. ansonsten kann ein int in ein double konvertiert werden. das ergebnis einer solchen konvertierung ist aber ein rvalue - folglich wird ein temporary erzeugt, dass sich folgerichtig nicht ändert, wenn i geändert wird. (wenn ich mich richtig erinnere dient obiges beispiel insbesondere zur begründung, warum rvalues nicht an referenzen auf nicht const gebunden werden können)