Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

31

24.06.2009, 14:44

Zitat von »"dot"«

Natürlich kann man const wegcasten. Allerdings braucht das den Compiler nicht zu kümmern. Du kannst bei deinem Auto auch die Räder absägen, dann den Hersteller auf Garantie zu klagen ist wieder eine andre Geschichte... Was const ist wird vom Compiler als const behandelt. Wenn du mit const_cast Mist baust bist du selber schuld (das nennt man dann undefined behaviour). Nur weil man const verwendet bedeutet das noch lange nicht dass man const correct ist...
Wenn ich die Räder absäge mache ich etwas, das nicht vom Hersteller vorgesehen ist. const_casts sind zwar unschön, aber vorgesehen und vollständig definiert. Mit undefined behaviour hat das nichts zu tun.

Ciao
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

the[V]oid

Alter Hase

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

32

24.06.2009, 15:38

Aha? Wenn ich also zum Beispiel einen als const markierten Parameter in einer Callback-Funktion einer Library einfach mal zu nicht-const caste und veränder, dann ist das vom Hersteller der Library vorgesehen?
<< an dieser Stelle ist eine Signatur verstorben >>

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

33

24.06.2009, 16:14

...

Natürlich nicht vom Hersteller der Lib! Aber darum geht es doch nicht. Es ging um den Compiler und die Sprache unterstützt das schon, auch wenn man das nicht ausnutzen sollte. Deshalb kann der Compiler da auch nicht optimieren, weil es sein könnte, dass die Lib absichtlich einen const Parameter übergibt, den man dann casten und verändern soll.
Du musst auch zwischen "vom Programmierer intendiert" und "undefiniertes Verhalten" unterscheiden ;) Selbst wenn in deinem Beispiel der Nutzer in der Callbackfunktion den Wert castet und verändert wird kein undefiniertes Verhalten entstehen. Es werden nur die Nutzungsregeln, welche in Dokus verfasst sind und durch Hilfsmittel wie public, friend, const und mutable direkt im Code stehen gebrochen. Aber wie gesagt, die Sprache unterstützt das Brechen dieser Regeln.

Ciao
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

34

24.06.2009, 16:19

const refence parameter können doch sowieso nur bei inlines wegoptimeirt werden, und nciht bei libcalls, oder?
und bei inlines hat der compiler ja den überblick, ob da n const_cast rumläuft.

FalkT

Treue Seele

Beiträge: 125

Wohnort: AC

  • Private Nachricht senden

35

24.06.2009, 17:32

Zitat von »"Helmut"«


Hi,
hast du dafür Quellen? Ich halte das nämlich für ziemlich großen Quatsch.. const kann nämlich weggecastet oder mit mutable umgangen werden, der Compiler kann also bei Libcalls nicht davon ausgehen, dass ein übergebenes Objekt unverändet bleibt. Und bei moduleigenen Funktionen kann der Compiler genauso gut ohne const herausfinden, ob ein Objekt verändert wird.
Das ist natürlich kein Grund const zu meiden.

Ciao


1. Quellen, die Zahl hab ich von Arbeitskollegen, die schon seit Fortran(77) dabei sind. Die haben auch diverse Tests mit unserer Software durchgeführt.

2. Immutable genau der Punkt. So ein C++-Guru bin ich jetzt nicht um zu sagen, ent-consten von externen Variablen liefert streng genommen undefiniertes Verhalten. Im Zweifel schreibst du an eine Stelle im Speicher, obwohl du das nicht solltest (Update von abhängigen Werten?).

3. Compiler? Ganz wichtiger Punkt !
Was der so erkennt ist doch relevant.

Zitat


kann der Compiler genauso gut ohne const herausfinden

Das ist eine Annahme deinerseits. Konnte der gcc 2.95 definitiv nicht!
Der 4er-gcc erkennt schon sehr viele const-Konstruktionen, die nicht als const deklariert sind, von daher schwindet der gennante Geschwindigkeitsvorteil heutzutage.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

36

24.06.2009, 22:23

Zitat von »"Helmut"«

const_casts sind zwar unschön, aber vorgesehen und vollständig definiert. Mit undefined behaviour hat das nichts zu tun.


Das Verhalten von const_cast ist vollständig definiert, ja. Das bedeutet aber noch lange nicht dass jeder beliebige Weg das Ergebnis eines const_cast zu verwenden definiert ist...

Zitat von »"Helmut"«

Deshalb kann der Compiler da auch nicht optimieren, weil es sein könnte, dass die Lib absichtlich einen const Parameter übergibt, den man dann casten und verändern soll.


Eine solche lib würd ich net benutzen weil die Entwickler der lib offenbar keine Ahnung von C++ haben.

Zitat von »"Helmut"«

Selbst wenn in deinem Beispiel der Nutzer in der Callbackfunktion den Wert castet und verändert wird kein undefiniertes Verhalten entstehen.


Doch, das gibt eindeutig undefiniertes Verhalten.

Zitat von »"Helmut"«

Aber wie gesagt, die Sprache unterstützt das Brechen dieser Regeln.


Nein, die Sprachdefinition sagt dass jegliche Modifikation eines const Objektes zu undefiniertem Verhalten führt. Einzige Ausnahme sind als mutable deklarierte Member von benutzerdefinierten Typen.

Zitat von »"Helmut"«

[...] const kann nämlich weggecastet oder mit mutable umgangen werden, der Compiler kann also bei Libcalls nicht davon ausgehen, dass ein übergebenes Objekt unverändet bleibt.


Doch, wenn der übergebene Parameter entsprechend const qualifiziert ist kann er das.

Helmut

5x Contest-Sieger

Beiträge: 692

Wohnort: Bielefeld

  • Private Nachricht senden

37

25.06.2009, 14:15

Zitat von »"dot"«

Zitat von »"Helmut"«

Aber wie gesagt, die Sprache unterstützt das Brechen dieser Regeln.


Nein, die Sprachdefinition sagt dass jegliche Modifikation eines const Objektes zu undefiniertem Verhalten führt. Einzige Ausnahme sind als mutable deklarierte Member von benutzerdefinierten Typen.
Naja man muss differenzieren. Wenn ein Objekt ursprünglich mit const deklariert wurde ist eine Veränderung natürlich nicht definiert, meistens werden solche Datenbereiche ja auch im ReadOnly Speicher gehalten. Bei einer const Referenz, die auf ein nicht-konstantes Objekt zeigt, ist das wegcasten von const aber legitim (10.2.7.1 The C++ Programming Language). Der Compiler kann also nur davon ausgehen, dass ein übergebener Parameter gleich bleibt, wenn er beweisen kann, dass die Referenz wirklich auf ein kontant deklariertes Objekt zeigt. Das ist nicht schwieriger, wenn man keine const Referenzen benutzt, was ich ja auch ursprünglich gesagt habe.
Aber ich gebe zu, dass ich mich nicht ganz richtig ausgedrückt habe...

Ciao
Sei stets geduldig gegenüber Leuten, die nicht mit dir übereinstimmen. Sie haben ein Recht auf ihren Standpunkt - trotz ihrer lächerlichen Meinung. (F. Hollaender)

kiba

Alter Hase

Beiträge: 327

Wohnort: NRW

Beruf: Azubi: Fach-Info. Anw.

  • Private Nachricht senden

38

25.06.2009, 14:48

Hab da noch 3 Fragen zum Thema.

Man sollte ja immer callbyref benutzen damit Klassen nicht immer kopiert werden müssen, und diese sollte man const setzen.
Aber wie sieht das dann aus wenn einfache Datentypen noch da sind.
Wie sollte man das am bessten schreiben.

C-/C++-Quelltext

1
void setfunk(int a,int b,const Obj& c,double d);

oder sieht das so besser aus:

C-/C++-Quelltext

1
void setfunk(const int a,const int b,const Obj& c,const double d);



C-/C++-Quelltext

1
2
3
4
5
6
7
class Surface{
private:
  //...

public:
const ubyte* getPixels();  //const Daten

ubyte* const getPixels();  //const Pointer

};

Wäre der konstante Pointer dazu geeignet?
-Die größe des Pixelarrays darf nicht verändert werden.
-Man darf auf die Pixel zugreifen und verändern

Sollte man Klassenfunktionen die eine Zeiger (einer mebervaraible) wiedergeben als eine Read-Only-Member-Funktionen also constant setzen.?

C-/C++-Quelltext

1
2
3
4
5
6
class Surface{
private:
  //...

public:
  ubyte* const getPixels() const;
};

Denn dann könnte man doch diese Funktion doch in einen konstanten Object aufrufen und die Varaible durch den zeiger verändern.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

39

25.06.2009, 15:37

Zitat von »"Helmut"«

Naja man muss differenzieren. Wenn ein Objekt ursprünglich mit const deklariert wurde ist eine Veränderung natürlich nicht definiert, meistens werden solche Datenbereiche ja auch im ReadOnly Speicher gehalten. Bei einer const Referenz, die auf ein nicht-konstantes Objekt zeigt, ist das wegcasten von const aber legitim (10.2.7.1 The C++ Programming Language).


Ja das stimmt schon. Es ist legitim das const wegzucasten, klar. Allerdings:

Zitat von »"Helmut"«

Der Compiler kann also nur davon ausgehen, dass ein übergebener Parameter gleich bleibt, wenn er beweisen kann, dass die Referenz wirklich auf ein kontant deklariertes Objekt zeigt.


Der Compiler muss gar nichts beweisen. Es liegt in der Verantwortung des Programmieres const_cast richtig einzusetzen, das ist es ja worauf ich die ganze Zeit hinauswill ;)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
void blob(const int& x)
{
  int* a = const_cast<int*>(&x);

  *a = 10;

  if (x == 5)
  {
    // ...

  }
}


Sowas is undefiniert...

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

40

25.06.2009, 15:49

Zitat von »"kiba"«

Man sollte ja immer callbyref benutzen damit Klassen nicht immer kopiert werden müssen, und diese sollte man const setzen.
Aber wie sieht das dann aus wenn einfache Datentypen noch da sind.
Wie sollte man das am bessten schreiben.


Richtig, das mit dem immer sollte man etwas relativieren. Für Primitive Typen gilt diese Faustregel auf jeden Fall nicht, die würd ich immer by Value übergeben, außer du willst das Original verändern...

Zitat von »"kiba"«


C-/C++-Quelltext

1
2
3
4
5
6
7
class Surface{
private:
  //...

public:
const ubyte* getPixels();  //const Daten

ubyte* const getPixels();  //const Pointer

};

Wäre der konstante Pointer dazu geeignet?
-Die größe des Pixelarrays darf nicht verändert werden.
-Man darf auf die Pixel zugreifen und verändern


Das const beim ubyte* const hier ist ziemlich sinnlos ;)


Zitat von »"kiba"«

Sollte man Klassenfunktionen die eine Zeiger (einer mebervaraible) wiedergeben als eine Read-Only-Member-Funktionen also constant setzen.?

C-/C++-Quelltext

1
2
3
4
5
6
class Surface{
private:
  //...

public:
  ubyte* const getPixels() const;
};

Denn dann könnte man doch diese Funktion doch in einen konstanten Object aufrufen und die Varaible durch den zeiger verändern.


Gute Frage :)

Hier würde man evtl. const overloading einsetzen:

C-/C++-Quelltext

1
2
3
4
5
6
7
class Surface {
private:
  //...

public:
  const ubyte* getPixels() const;
  ubyte* getPixels();
};


Wenn du ein const Surface hast kannst du die Pixel nicht verändern (wird die erste Variante von getPixels benutzt), sonst schon...

Werbeanzeige