_
Ich habe mir mal die recht anregende Diskussion und die Begruendung der c-faq durchgelesen.
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
Erst habe ich mich gefragt: Warum erlaubt der Compiler in Zeile 4, dass einem char* ein const char* zugewiesen wird? Dann habe ich gemerkt, dass *p2(also p1) dadurch dass Zeile 3 ausgefuehrt wurde nicht mehr nur ein char* ist, sondern in p2 als ein const char* aufgefasst wird.
Die Speicherstelle(!) von p1 wird also unterschiedlich interpretiert. p1 selber in Zeile 2 glaubt, seinen Referenten modifizieren zu duerfen. *p2 in Zeile 4 hingegen glaubt, dass jene Speicherstelle ihren Referenten NICHT modifizieren darf. Diese Diskrepanz fuehrt dazu, dass man sich mit der Initialisierung aus Zeile 3 quasi "den Wolf im Schafspelz" ins Haus holt. In Zeile 4 faellt dann p2 auf diesen "Schafspelz" herein und verleiht p1 das Privileg auf einen const char zu zeigen, ohne selbst ein const char* zu sein, was sonst aber nur denen vorbehalten ist. Und genau um das zu vermeiden meckert der Compiler bei Zeile 3.
Das daraus resultierende Dilemma ist zugegebenermassen recht unwahrscheinlich, jedoch so wie ich die Begruendung der c-faq verstehe soll bei einer const-Initialisierung(wie z.B. in Zeile 3) jeder denkbar moegliche Fall ausgeschlossen werden, dass irgendwie Schreibzugriff auf eine durch const geschuetzte variable erschlichen wird. Ein language feature, das zulaesst eine Variable vom Typ Pointer-auf-const-T mit einer Variablen vom Typ Pointer-auf-T zu initialisieren darf es nicht geben. Die einzige Ausnahme ist es, wenn T ein nicht-Pointer Typ ist.
Das war jetzt z.T. etwas bildlich gesprochen, aber vielleicht wird es dadurch anschaulicher
Mein Compiler ist uebrigens ein
UniX:~$ g++ -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu
Thread model: posix
gcc version 4.1.2 20060729 (prerelease) (Debian 4.1.1-10)
Die c-faq wies ja darauf hin, dass
C++ would still not allow assigning a char ** to a const char **
von daher kann es gut sein, dass der gcc den Code uebersetzt, der g++ hingegen nicht.
So hab ich die Sache verstanden.