2016-10-07 5 views
0

Betrachten Sie unten zwei Fälle. case1: Compiler-Fehler -> Fehler: Zuwachs von read-only Variable ‚x‘Constant int incement

#include<stdio.h> 
    main() 
    { 
    const int x=5; 
    printf("%d",++x); 
    } 

case2: Ran erfolgreich mit Ausgang 6. warum?

#include<stdio.h> 
    main() 
    { 
    const int x=5; 
    int *ptr=&x; 
    ++(*ptr); 
    printf("%d",x); 
    } 
+3

Die zweite führt zu * undefiniertem Verhalten *. Sie verwenden einen Zeiger auf nicht-konstantes 'int', um eine Konstante' int' zu ändern. Ein guter Compiler sollte davor warnen und wenn nicht, sollten Sie weitere Warnungen aktivieren. –

+1

Warnung: Die Initialisierung verwirft Qualifier vom Zeigerzieltyp –

+0

Also sollte case2 int const * ptr = & x sein, um das gleiche Verhalten wie in case1 zu erhalten. –

Antwort

3

int *ptr=&x; ist eine Einschränkungsverletzung, das heißt ein "Fehler", ungültiger Code. Die C-Sprache unterstützt keine implizite Konvertierung von const int * in den Typ int *. Ihr Compiler hat dafür sicher eine Diagnosemeldung ausgegeben.

Nach dieser Diagnosemeldung wird das Verhalten Ihres Programms nicht mehr von der C-Sprache definiert, vorausgesetzt, Ihr Compiler ist irgendwie damit einverstanden, es zu kompilieren. Viele C-Compiler können so konfiguriert werden, dass sie diesen Code nicht kompilieren, selbst wenn sie ihn im Standardmodus akzeptieren.

Sie könnten die Umwandlung erzwingen, indem eine gegossene

int *ptr = (int *) &x; 

Verwendung Dies würde die Beseitigung der obigen Einschränkungsverletzung erhalten. Die Compiler müssten nun Ihren Code akzeptieren (mit einigen Vorbehalten). Aber nach dieser Änderung würde der Versuch, ++*ptr zu tun, undefiniertes Verhalten auslösen, weil es ein Versuch ist, ein const Objekt zu modifizieren.

+0

Also sollte die case2 int const * ptr = & x sein, um das gleiche Verhalten wie in case1 zu bekommen. –

+0

@Vijay S B: Ja, das ist eine Möglichkeit, es zu tun. Sie könnten auch eine explizite Konvertierung (siehe oben) erzwingen, um den Fehler loszuwerden, aber stattdessen in UB zu laufen. – AnT