Dies ist kein akademischer Code oder eine hypothetische Frage. Das ursprüngliche Problem bestand darin, Code von HP11 in HP1123 Itanium zu konvertieren. Im Grunde läuft es auf einen Kompilierungsfehler auf HP1123 Itanium hinaus. Es hat mir wirklich den Kopf verkratzt, wenn ich es zu Studienzwecken auf Windows vervielfältige. Ich habe alle außer den grundlegendsten Aspekten entfernt ... Möglicherweise müssen Sie die Steuerung D drücken, um ein Konsolenfenster zu verlassen, wenn Sie es wie folgt ausführen:
%Vor%Hier ist die Ausgabe
%Vor%Alles, was ich sagen kann, ist was zum Teufel? Ist es undefiniert, dies zu tun? Es ist die kontraintuitivste Sache, die ich für solch ein einfaches Beispiel gesehen habe.
Aktualisierung:
Tatsächlich nach dem Suchen nach einer Weile das Menü Debug & gt; & gt; Windows & gt; & gt; Demontage hatte genau die Optimierung, die unten beschrieben wurde.
%Vor%Danke euch allen!
Sieht so aus, als würde der Compiler optimieren
%Vor%in
%Vor% seit Sie sagten dass IAMCONST
ein const int
ist.
Aber da du die Adresse von IAMCONST
nimmst, muss sie irgendwo auf dem Stack liegen und die const
ness kann nicht erzwungen werden, also der Speicher an dieser Stelle ( *pTOCONST
) ist doch veränderlich.
Kurz gesagt: Sie haben die const
ness weggeworfen, tun Sie das nicht. Armes, wehrloses C ...
Verwenden von GCC für x86, mit -O0
(keine Optimierungen), der generierten Assembly
kopiert von *(bp-12)
auf dem Stapel zu printf
's Argumente. Verwenden Sie jedoch -O1
(sowie -Os
, -O2
, -O3
und andere Optimierungsstufen),
Sie können deutlich sehen, dass stattdessen die Konstante 3
verwendet wird.
Wenn Sie Visual Studio CL.EXE
verwenden, deaktiviert /Od
die Optimierung. Dies variiert von Compiler zu Compiler.
Seien Sie gewarnt, dass die C-Spezifikation zulässt, dass der C-Compiler davon ausgeht, dass das Ziel eines int *
-Zeigers niemals überlappt der Speicherort eines const int
, also sollten Sie das überhaupt nicht tun, wenn Sie vorhersehbares Verhalten wollen.
Der konstante Wert IAMCONST wird in den printf-Aufruf eingebunden.
Was Sie tun, ist bestenfalls falsch und wahrscheinlich vom C ++ - Standard undefiniert. Mein rate ist, dass der C ++ - Standard den Compiler frei lässt, ein const-Primitiv zu inline zu schreiben, das lokal für eine Funktionsdeklaration ist. Der Grund dafür ist, dass der Wert nicht geändert werden kann.
Andererseits ist es C ++, wo es sehr unterschiedliche Wörter geben kann und kann.
Sie haben Glück, dass der Compiler die Optimierung durchführt. Eine alternative Behandlung bestünde darin, die Konstante const in den Nur-Lese-Speicher zu setzen, woraufhin der Versuch, den Wert zu ändern, einen Core-Dump verursachen würde.
Schreiben in ein konstantes Objekt durch einen Cast, der const entfernt, ist undefiniertes Verhalten - also an dem Punkt, an dem Sie dies tun:
%Vor%Alle Wetten sind aus.
Aus dem C ++ - Standard 7.1.5.1 (Die cv-Qualifikationsmerkmale):
Mit Ausnahme dessen, dass ein beliebiges deklariertes Klasse-Member (7.1.1) geändert werden kann, jeder Versuch, ein const Objekt während seiner Lebensdauer (3.8) führt zu undefiniertem Verhalten.
Aus diesem Grund kann der Compiler davon ausgehen, dass sich der Wert von IAMCONST
nicht ändert, sodass der Zugriff auf den tatsächlichen Speicher optimiert werden kann. Wenn die Adresse des const-Objekts nie genommen wird, kann der Compiler den gesamten Speicher für das Objekt eliminieren.
Beachten Sie auch (wieder in 7.1.5.1):
Eine Variable eines nichtflüchtigen Const-qualifizierten Integral- oder Enumerationstyps, die durch einen ganzzahligen konstanten Ausdruck initialisiert wird, kann in Integralkonstantenausdrücken verwendet werden (5.19).
Dies bedeutet, dass IAMCONST in Kompilierungskonstantenausdrücken verwendet werden kann (z. B. um einen Wert für eine Enumeration oder die Größe eines Arrays bereitzustellen). Was würde es bedeuten, das zur Laufzeit zu ändern?
Es spielt keine Rolle, ob der Compiler optimiert wird oder nicht. Sie haben nach Ärger gefragt und Sie haben Glück, dass Sie sich selbst die Mühe gemacht haben, anstatt darauf zu warten, dass die Kunden Ihnen das melden.
"Alles was ich sagen kann, ist was zum Teufel? Ist es unbestimmt das zu tun? Es ist das widersinnigste was ich für solch ein einfaches Beispiel gesehen habe."
Wenn du das wirklich glaubst, dann musst du zu einer Sprache wechseln, die du verstehen kannst, oder den Beruf wechseln. Nutzen Sie C und C ++ oder C # für sich und Ihre Kunden.
%Vor%Du hast es gesagt.
%Vor%Erraten Sie, warum der Compiler sich beschwert hat, wenn Sie Ihre böse Besetzung ausgelassen haben. Der Compiler hat vielleicht die Wahrheit gesagt, bevor Sie ihn belogen haben.
"Wird der Böse Zauber vom bösen Compiler übertrumpft?"
Nein. Die böse Besetzung wird von sich selbst übertrumpft. Ob dein Compiler versuchte, dir die Wahrheit zu sagen, der Compiler war nicht böse.
Tags und Links c++