[Bearbeiten: OK, diese Frage ist subtiler als ich zuerst dachte.]
Das Deklarieren eines Zeigers auf const oder einer Referenz von const hilft keinem Compiler, etwas zu optimieren. (Siehe auch das Update am Ende dieser Antwort.)
Die const
Erklärung gibt nur an, wie ein Bezeichner im Rahmen seiner Erklärung verwendet wird. Es heißt nicht, dass sich das zugrunde liegende Objekt nicht ändern kann.
Beispiel:
int foo(const int *p) {
int x = *p;
bar(x);
x = *p;
return x;
}
Der Compiler kann nicht davon ausgehen, dass *p
dies durch den Aufruf von nicht geändert wird bar()
, da p
dies (z. B.) ein Zeiger auf ein globales int sein und es bar()
möglicherweise ändern kann.
Wenn der Compiler genug über den Aufrufer von weiß foo()
und der Inhalt, von bar()
dem er beweisen kann, dass er bar()
sich nicht ändert *p
, kann er diesen Beweis auch ohne die const-Deklaration ausführen .
Dies gilt jedoch im Allgemeinen. Da sich dies const
nur im Bereich der Deklaration auswirkt, kann der Compiler bereits sehen, wie Sie den Zeiger oder die Referenz in diesem Bereich behandeln. Es ist bereits bekannt, dass Sie das zugrunde liegende Objekt nicht ändern.
Kurz gesagt, alle const
in diesem Zusammenhang tun, ist zu verhindern, dass Sie Fehler machen. Es sagt dem Compiler nichts, was er noch nicht weiß, und ist daher für die Optimierung irrelevant.
Was ist mit Funktionen, die aufrufen foo()
? Mögen:
int x = 37;
foo(&x);
printf("%d\n", x);
Kann der Compiler beweisen, dass dies 37 druckt, da foo()
ein const int *
?
Nein. Auch wenn foo()
ein Zeiger auf const benötigt wird, kann dies die Konstanz wegwerfen und das int ändern. (Dies ist kein undefiniertes Verhalten.) Auch hier kann der Compiler im Allgemeinen keine Annahmen treffen. und wenn es genug weiß, um foo()
eine solche Optimierung vorzunehmen, wird es das auch ohne die wissen const
.
Die einzige Zeit const
, in der Optimierungen möglich sind, sind folgende Fälle:
const int x = 37;
foo(&x);
printf("%d\n", x);
Hier bedeutet das Modifizieren x
durch irgendeinen Mechanismus (z. B. indem man einen Zeiger darauf nimmt und den wegwirft const
), dass man undefiniertes Verhalten aufruft. Der Compiler kann also davon ausgehen, dass Sie dies nicht tun, und er kann die Konstante 37 in printf () übertragen. Diese Art der Optimierung ist für jedes von Ihnen deklarierte Objekt zulässig const
. (In der Praxis ist eine lokale Variable, auf die Sie niemals verweisen, nicht von Vorteil, da der Compiler bereits sehen kann, ob Sie sie in seinem Umfang ändern.)
Um Ihre "Randnotiz" -Frage zu beantworten, (a) ist ein const-Zeiger ein Zeiger; und (b) ein konstanter Zeiger kann gleich NULL sein. Sie haben Recht, dass die interne Darstellung (dh eine Adresse) höchstwahrscheinlich dieselbe ist.
[aktualisieren]
Wie Christoph in den Kommentaren betont, ist meine Antwort unvollständig, weil sie nicht erwähnt wirdrestrict
.
In Abschnitt 6.7.3.1 (4) der C99-Norm heißt es:
Während jeder Ausführung von B sei L ein beliebiger l-Wert, dessen & L auf P basiert. Wenn L verwendet wird, um auf den Wert des von ihm bezeichneten Objekts X zuzugreifen, und X ebenfalls (auf irgendeine Weise) geändert wird, gelten die folgenden Anforderungen : T darf nicht qualifiziert sein. ...
(Hier ist B ein Basisblock, über den sich P, ein Beschränkungszeiger auf T, im Geltungsbereich befindet.)
Wenn also eine C-Funktion foo()
wie folgt deklariert ist:
foo(const int * restrict p)
... dann der Compiler kann davon ausgehen , dass keine Änderungen *p
während der Laufzeit auftreten p
- dh während der Ausführung foo()
- weil sonst das Verhalten nicht definiert wäre.
Also im Prinzip kombinieren restrict
mit einem Zeiger auf const beide Optimierungen ermöglichen, die oben verworfen wurden. Implementieren Compiler tatsächlich eine solche Optimierung, frage ich mich? (GCC 4.5.2 zumindest nicht.)
Beachten Sie, dass restrict
nur in C vorhanden ist, nicht in C ++ (nicht einmal in C ++ 0x), außer als compilerspezifische Erweiterung.
const
, aber hauptsächlich für Menschen und den Code, den wir schreiben. Der Compiler kann nichts vertrauen und kann daher nicht in gleicher Weise davon profitieren.