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

1

07.09.2009, 17:51

Konstante wird ersetzt

Hi Forum!
Mir kam gerade die Idee, eine konstante Variable zu ändern und hab dazu auch was gefunden.
Im Allgemeinen scheint es auch zu funktionieren, bei der Ausgabe stell ich jedoch fest, dass der Wert anscheinend doch nicht geändert wurde.

Der Assemblycode sagt mir (hab nie wirklich viel mit Assembler gemacht), dass er nicht den "wirklichen Wert" der Konstante nimmt, sondern er diese durch den Wert, mit dem ich sie initialisiert hab, ersetzt.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <conio.h>
#include <iostream>
#include "windows.h"
using namespace std;

int main()
{
    const int a = 4;
    const int* b = &a;

    cout << a << endl;

    int* c = const_cast<int*>(b);
    *c = 5;

    cout << a << endl;

    getch();
}


Ein paar Auszüge des erzeugten Codes:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
; 8    :    const int a = 4;

  0001e c7 45 f8 04 00
    00 00        mov     DWORD PTR _a$[ebp], 4

; 9    :    const int* b = &a;

  00025 8d 45 f8     lea     eax, DWORD PTR _a$[ebp]
  00028 89 45 ec     mov     DWORD PTR _b$[ebp], eax



; 11   :    cout << a << endl;
  00035 6a 04        push    4


Die letzte Zeile scheint wohl das Problem zu sein.
Gibt es dafür eine einfache Erklärung? Mir ist es nicht so wichtig, dass das funktioniert (ist ja eh hässlich, gefährlich usw.; wollte ich auch nicht wirklich einsetzen), aber mich würde interessieren, aus welchem Grund er das macht.


Wenn ich im ganzen Code nur eine Konstante verwende und diese ausgib, erscheinen die ersten 2 Zeilen des hier geposteten Assemblycodes ebenfalls. Das deutet für mich darauf hin, dass die Konstante irgendwo irgendwelchen Speicher belegt. Laut Stroustrup sollte sie das aber nicht, wenn zur Compilezeit klar ist, welchen Wert sie hat und wenn nicht auf die Adresse zugegriffen wird.

Wie gesagt, rein aus Interesse.

the[V]oid

Alter Hase

Beiträge: 775

Wohnort: Aachen

  • Private Nachricht senden

2

07.09.2009, 17:54

Darf ich mal kurz fragen, warum du absichtlich undefiniertes Verhalten provozierst?
<< an dieser Stelle ist eine Signatur verstorben >>

3

07.09.2009, 17:57

Weiß auch nicht richtig :-D
Wollte halt mal schauen, was passiert, wenn... ;)
Ist es eig. in jedem Fall undefiniertes Verhalten, wenn man irgendwie versucht, eine Konstante zu ändern?

Edit: Dieser Teil dürfte trotzdem nichts mit undefiniertem Verhalten zu tun haben :)

Zitat

Wenn ich im ganzen Code nur eine Konstante verwende und diese ausgib, erscheinen die ersten 2 Zeilen des hier geposteten Assemblycodes ebenfalls. Das deutet für mich darauf hin, dass die Konstante irgendwo irgendwelchen Speicher belegt. Laut Stroustrup sollte sie das aber nicht, wenn zur Compilezeit klar ist, welchen Wert sie hat und wenn nicht auf die Adresse zugegriffen wird.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

4

07.09.2009, 18:00

Zitat von »"defaultplayer^^


Ist es eig. in jedem Fall undefiniertes Verhalten, wenn man irgendwie versucht, eine Konstante zu ändern?


Jup.

Wegen deiner eigentlichen Frage. Es kann gut sein, dass der Compiler dir da doch Speicher belegt für Debugging Zwecke o.ä. Aber im Relase wird das dann drausen sein. (nur eine Vermutung).

5

07.09.2009, 18:53

Zitat

Zitat

Ist es eig. in jedem Fall undefiniertes Verhalten, wenn man irgendwie versucht, eine Konstante zu ändern?

Jup.

Schade.
Hab auch dieses Problem bis jetzt noch nicht behoben. Wenn das so ist, werd ich es wohl nach noch ein wenig rumspielen sein lassen.

Mit deiner Vermutung hattest Recht, habs mir gerade mal im Release angeschaut, alles so, wie es sein muss. :)

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

6

07.09.2009, 19:10

Zitat von »"defaultplayer^^

Zitat

Zitat

Ist es eig. in jedem Fall undefiniertes Verhalten, wenn man irgendwie versucht, eine Konstante zu ändern?

Jup.

Schade.
Hab auch dieses Problem bis jetzt noch nicht behoben. Wenn das so ist, werd ich es wohl nach noch ein wenig rumspielen sein lassen.


Was für ein Problem? - Konstanen sollen immer Konstant sein, ansonsten sinds Variablen. ;)

Und wenn das Problem ist, dass du keine dynamische Arrays machen kannst, dann nimmst du besser einen Standardcontainer, wie z.B std::vector.

7

07.09.2009, 21:14

Ja, ist kein richtiges Problem. Ich wollte einfach mal, dass die Konstante nicht konstant ist 8)

std::vector sowie new und delete([]) sind mir bekannt, hatte nichts damit zu tun :).

Trotzdem vielen Dank, immerhin hat sich die eine Frage geklärt.

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

8

07.09.2009, 21:23

Zitat von »"defaultplayer^^

Ja, ist kein richtiges Problem. Ich wollte einfach mal, dass die Konstante nicht konstant ist 8)


Kommt ganz drauf an wo die Werte "gelagert" werden. Und wie strikt der Compiler das sieht und was er unternimmt um dich von deinem Vorhaben abzuhalten/zu unterstützen... Fazit: Undefined behavior will echt keiner haben!

9

07.09.2009, 22:59

Wäre das Verhalten auch noch undefiniert, wenn der Compiler immer den Wert im Speicher nehmen würde?


Ich hab gerade bemerkt, dass der Code (im Grunde der von vorher) funktioniert (also die Konstante geändert wird), wenn ich bei VS einstelle, dass er es als C-Code kompilieren soll.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <conio.h>
#include <stdio.h>

int main()
{
    const int a = 4;
    int* c;

    printf("%d\n", a);

    c = (int*)&a; // <<<<<<

    *c = 5;

    printf("%d\n", a);

    getch();
}


Bei der markierten Zeile ist, wenn der Code als C-Code behandelt wird, der explizite Cast nicht notwendig.

drakon

Supermoderator

Beiträge: 6 513

Wohnort: Schweiz

Beruf: Entrepreneur

  • Private Nachricht senden

10

07.09.2009, 23:11

Ich kenne den C Standard jetzt nicht, aber ich denke, dass es auch da auf undefiniert hinaus läuft..

Werbeanzeige