Fehler nach Compiler-Update
-
Ramanujan schrieb:
Was bedeutet "cv-qualifiziert"?
Tut mir Leid.

Also, diese Funktion ist cv-qualifiziert:class foo { void bar() const {} //Kennste doch, oder? };Ramanujan schrieb:
Was ist der Unterschied zwischen logischer und physikalischer constness?
Ein Objekt ist physikalisch const, wenn sein Speicher komplett geschützt ist.
Ein Objekt ist nur logisch const, wenn es zwar logisch gesehen nach dem Aufruf einer Funktion immer noch gleich ist, sein Speicher aber evt. verändert wurde.
-
Sone schrieb:
mutable ist dazu da, die physikalische constness auszuheben und daraus eine logische constness zu machen - so, dass selbst in cv-qualifizierten Membermethoden
mutableMember verändert werden können. Diese Member sind aber nach aussen hinconst.Das heißt, dass auch in konstanten Methoden diese Member verändert werden können. Mit dem Unterschied von logischer und physischer Constness würde ich das jetzt nicht in Verbindung bringen. [EDIT: Ok, das passt schon. Hatte da eine andere Definition von physischer Constness im Kopf, nämlich die tatsächliche Unmöglichkeit der Veränderung des Wertes (Read-Only-Speicher, z.B.)]
-
Mr X schrieb:
Sone schrieb:
mutable ist dazu da, die physikalische constness auszuheben und daraus eine logische constness zu machen - so, dass selbst in cv-qualifizierten Membermethoden
mutableMember verändert werden können.Das heißt, dass auch in konstanten Methoden diese Member verändert werden können. Mit dem Unterschied von logischer und physikalischer Constness würde ich das jetzt nicht in Verbindung bringen.
Findest du? Find ich nicht.
HIer wieso:
Wenn es keine mutable Member gibt, ist der Speicher der Klasse ja geschützt, damit ist das Object physikalisch const. Wenn es mutable Member gibt, existiert theoretisch nur noch die logische constness- der speicher kann teilweise auch für const-Objekte verändert werden.
-
Hatte da eine andere Definition von physischer Constness im Kopf, nämlich die tatsächliche Unmöglichkeit der Veränderung des Wertes (Read-Only-Speicher, z.B.)
Und das ist die meinige

P.S.: Das mit den Funktionen ist soweit ich sehe quatsch. Ich hab da selbst was durcheinander gebracht.
Die Funktion ist halt logisch const, wenn sie (wie ich sagte) nur den logischen Wert des Objektes nicht verändert, jedoch den physikalischen.
Eine Funktion ist dagegen physikalisch const, wenn sie das Objekt gar nicht verändert.
-
Sone schrieb:
Mr X schrieb:
Sone schrieb:
mutable ist dazu da, die physikalische constness auszuheben und daraus eine logische constness zu machen - so, dass selbst in cv-qualifizierten Membermethoden
mutableMember verändert werden können.Das heißt, dass auch in konstanten Methoden diese Member verändert werden können. Mit dem Unterschied von logischer und physikalischer Constness würde ich das jetzt nicht in Verbindung bringen.
Findest du? Find ich nicht.
HIer wieso:
Wenn es keine mutable Member gibt, ist der Speicher der Klasse ja geschützt, damit ist das Object physikalisch const. Wenn es mutable Member gibt, existiert theoretisch nur noch die logische constness- der speicher kann teilweise auch für const-Objekte verändert werden.
Während Du das geschrieben hast, habe ich da noch eine Anmerkung in meinen Beitrag hineineditiert. Hatte eine andere Definition von phyischer/logischer Konstanz im Kopf. Allerdings muss man bei deiner Definition eines bedenken: Es ist möglich, den Speicherinhalt (wenn auch nur mit üblen Hacks) zu verändern, selbst wenn das Objekt physisch Konstant ist.
-
Mr X schrieb:
Allerdings muss man bei deiner Definition eines bedenken: Es ist möglich, den Speicherinhalt (wenn auch nur mit üblen Hacks) zu verändern, selbst wenn das Objekt physisch Konstant ist.
Das wusste ich nicht. Erzähl.

-
Sone schrieb:
Hatte da eine andere Definition von physischer Constness im Kopf, nämlich die tatsächliche Unmöglichkeit der Veränderung des Wertes (Read-Only-Speicher, z.B.)
Und das ist die meinige

P.S.: Das mit den Funktionen ist soweit ich sehe quatsch. Ich hab da selbst was durcheinander gebracht.
Die Funktion ist halt logisch const, wenn sie (wie ich sagte) nur den logischen Wert des Objektes nicht verändert, jedoch den physikalischen.
Eine Funktion ist dagegen physikalisch const, wenn sie das Objekt gar nicht verändert.Nun, ich dachte eher, du definierst es so:
physische Konstanz: Der Speicherinhalt bleibt unverändert.
logische Konstanz: Das Objekt "sieht" von außen gleich aus.
-
Sone schrieb:
Mr X schrieb:
Allerdings muss man bei deiner Definition eines bedenken: Es ist möglich, den Speicherinhalt (wenn auch nur mit üblen Hacks) zu verändern, selbst wenn das Objekt physisch Konstant ist.
Das wusste ich nicht. Erzähl.

Ohne es getestet zu haben:
const int i = 5; int* p = (int*)&i; *p = 6; std::cout << i;Das _kann_ ein Exception auslösen, muss es aber nicht. Hängt vom Compiler/Laufzeitumgebung ab. Es kann auch 6 rauskommen.
Das gleiche kannst Du auch in cv-Methoden tun, indem du den this-Zeiger castest. Das dabei eine Ausnahme geworfen wird, halte ich übrigens für eher unwahrscheinlich.
-
Mr X schrieb:
Sone schrieb:
Hatte da eine andere Definition von physischer Constness im Kopf, nämlich die tatsächliche Unmöglichkeit der Veränderung des Wertes (Read-Only-Speicher, z.B.)
Und das ist die meinige

P.S.: Das mit den Funktionen ist soweit ich sehe quatsch. Ich hab da selbst was durcheinander gebracht.
Die Funktion ist halt logisch const, wenn sie (wie ich sagte) nur den logischen Wert des Objektes nicht verändert, jedoch den physikalischen.
Eine Funktion ist dagegen physikalisch const, wenn sie das Objekt gar nicht verändert.Nun, ich dachte eher, du definierst es so:
physische Konstanz: Der Speicherinhalt bleibt unverändert.
logische Konstanz: Das Objekt "sieht" von außen gleich aus.Ja, so definiere ich es. Für Objekte. Für Funktionen wie oben.
-
Sone schrieb:
Mr X schrieb:
Sone schrieb:
Hatte da eine andere Definition von physischer Constness im Kopf, nämlich die tatsächliche Unmöglichkeit der Veränderung des Wertes (Read-Only-Speicher, z.B.)
Und das ist die meinige

P.S.: Das mit den Funktionen ist soweit ich sehe quatsch. Ich hab da selbst was durcheinander gebracht.
Die Funktion ist halt logisch const, wenn sie (wie ich sagte) nur den logischen Wert des Objektes nicht verändert, jedoch den physikalischen.
Eine Funktion ist dagegen physikalisch const, wenn sie das Objekt gar nicht verändert.Nun, ich dachte eher, du definierst es so:
physische Konstanz: Der Speicherinhalt bleibt unverändert.
logische Konstanz: Das Objekt "sieht" von außen gleich aus.Ja, so definiere ich es. Für Objekte. Für Funktionen wie oben.
Genau. Dann passt deine Bemerkung von oben ja auch.
-
Cool! Der GCC macht es irgendwie komisch, er ignoriert die Anweisung komplett:
const int i = 5; int* p = (int*)&i; *p = 6; std::cout << i; //Ausgabe: 5Dasselbe bei meinem Hack:
int const a(5); memset(const_cast<void*>(reinterpret_cast<void const*>(&a)), 0, sizeof (a)); std::cout << a << '\n'; // 5Mr X schrieb:
Genau. Dann passt deine Bemerkung von oben ja auch.
Puah, schön dass das jetzt endlich geklärt ist

-
Sone schrieb:
Cool! Der GCC macht es irgendwie komisch, er ignoriert die Anweisung komplett:
const int i = 5; int* p = (int*)&i; *p = 6; std::cout << i; //Ausgabe: 5Dasselbe bei meinem Hack:
int const a(5); memset(const_cast<void*>(reinterpret_cast<void const*>(&a)), 0, sizeof (a)); std::cout << a << '\n'; // 5Das sieht so aus, also hat er die Konstante wegoptimiert. Ich probiers mal selbst aus.
-
Im MSVC gehts, da kommt 6 raus.Nein. Mein Fehler. Er wirft eine Ausnahme. Die Compiler sind sicherer, als ich gedacht habe.
-
An den TE: Ich hoffe, dein Problem mit mutable hat sich gelöst. Also nochmal: Mit mutable deklarierte Member dürfen auch in const-qualifizierten Funktionen verändert werden. Es kann also sein, dass in deinem Code vereinfacht folgendes steht:
class FrameworkBla { mutable size_t counter; FrameworkBla(): counter(0) {} void eine_Logisch_Konstante_Funktion() const { ++counter;//Hier wird counter verändert, obwohl die Instanz ja const ist! Ohne mutable wird es also einen einfachen semantischen Fehler geben. ........ } };
-
Was mich noch verwirrt: Sekunde mal! Wenn du deinen Compiler geupdatet hast, heißt das ja, dass der diesen falschen Code vorher geschluckt hat!

Notiz an mich: Dringend meinen GCC updaten.
-
So, jetzt hab ichs aber hingekriegt (Die Spielerei mit dem this-Zeiger funktioniert; Da gibts keine Exception und der Compiler (MSVC) funkt auch nicht dazwischen.):
#include <iostream> struct C { int i; C() : i(5) {} void foo() const { C* c = (C*)this; c->i = 6; } }; int main() { C c; c.foo(); std::cout << c.i; }
-
#include <iostream> struct C { int i; C() : i(5) {} void foo() const { C* c = (C*)this; c->i = 6; } }; int main() { C c; c.foo(); std::cout << c.i; }
Nochmal um das klarzustellen: Auf keinen Fall benutzen! Das ist UB und sehr unelegant.

-
Ramanujan schrieb:
mutable long const& m; //!< matrix row sizeGruselig. Memberreferenzen? Und dann auch noch mutable?
Bestimmt wird dann bei der Zuweisung auch noch wild mit Zeigern und Casts gewerkelt, um die Referenz umzubiegen. Es gibt eben Leute, die wollen sich das Bein wegschießen.Sone schrieb:
#include <iostream> struct C { int i; C() : i(5) {} void foo() const { C* c = (C*)this; c->i = 6; } }; int main() { C c; c.foo(); std::cout << c.i; }
Nochmal um das klarzustellen: Auf keinen Fall benutzen! Das ist UB und sehr unelegant.

Undefiniertes Verhalten findet sich hier nicht.
Das wäre erst dann der Fall, wenn das Objekt c auch const deklariert worden wäre. Der Versuch, ein mit const deklariertes Objekt wärend seiner Lebenszeit (nach Ende des Konstruktors, vor Beginn Destruktor bei Klassen) zu verändern, führt zu undefiniertem Verhalten. Im Umkehrschluss darf der Compiler annehmen, das ein const-deklariertes Objekt nicht verändert wird (und genau deshalb ist der andere Fall undefiniert - es geht in 99% der Fälle von UB um Optimierung. nicht etwa um irgendwelche hardweiseseitig schreibgeschützte Speicherbereiche). und kann somit Zugiffe auf diese konstanten Objekte direkt durch die Werte der initiaiisierenden Ausdrücke ersetzen.
Warum man so etwas überhaupt jemals schreiben wollte, ist auch nicht ganz klar...
-

camper schrieb:
Sone schrieb:
#include <iostream> struct C { int i; C() : i(5) {} void foo() const { C* c = (C*)this; c->i = 6; } }; int main() { C c; c.foo(); std::cout << c.i; }
Nochmal um das klarzustellen: Auf keinen Fall benutzen! Das ist UB und sehr unelegant.

Undefiniertes Verhalten findet sich hier nicht.
Das wäre erst dann der Fall, wenn das Objekt c auch const deklariert worden wäre.Das meinte ich...

Stand so ja in Stroustrups.
-
camper schrieb:
Gruselig. Memberreferenzen?
Was ist an Memberreferenzen so gruselig?