Domanda

#include <stdio.h>
int main()
{
    const int a = 12;
    int *p;
    p = &a;
    *p = 70;
}

Funzionerà?

È stato utile?

Soluzione

E ' "un comportamento indefinito", il che significa che in base allo standard non è possibile prevedere che cosa accadrà quando si tenta di questo. Può fare cose diverse a seconda della particolare macchina, compilatore, e lo stato del programma.

In questo caso, ciò che il più delle volte accadrà è che la risposta sarà "sì". Una variabile, const o no, è solo una locazione di memoria, e si può rompere le regole di costanza e semplicemente sovrascrivere. (Naturalmente questo causerà un grave errore se qualche altra parte del programma è in funzione i suoi dati const essere costante!)

Tuttavia, in alcuni casi - più tipicamente per i dati const static - il compilatore può mettere tali variabili in una regione sola lettura della memoria. MSVC, per esempio, di solito mette const int statici nel segmento .text dell'eseguibile, il che significa che il sistema operativo genererà un errore di protezione, se si tenta di scrivere ad esso, e il programma andrà in crash.

In qualche altra combinazione di compilatore e la macchina, qualcosa di completamente diverso può accadere. L'unica cosa che possono prevedere con certezza è che questo modello sarà infastidire chi deve leggere il codice.

Altri suggerimenti

E 'un comportamento indefinito. Dimostrazione:

/* program.c */

int main()
{
        const int a = 12;
        int* p;
        p = &a;
        *p = 70;
        printf("%d\n", a);
        return 0;
}


gcc program.c

ed eseguirlo. Uscita sarà il 70 (GCC 4.3)

Quindi compilate in questo modo:

gcc -O2 program.c

ed eseguirlo. L'uscita sarà 12. Quando lo fa ottimizzazione, il compilatore presumibilmente carichi 12 in un registro e non preoccuparsi di caricare nuovamente quando è necessario accedere ad un per printf perché "sa" che non può cambiare.

Modifica di un oggetto const qualificato tramite un puntatore invoca un comportamento indefinito, e tale è il risultato. E 'probabile che sia qualcosa che ci si aspetta, però, vale a dire. il valore precedente invariato, se è stato posto in .text, ecc.

E 'effettivamente funziona con gcc. Non piace, però:

  

test.c: 6: warning: scarta assegnazione qualificazioni dal tipo di destinazione puntatore

Ma il valore cambiò quando eseguito. Non voglio sottolineare l'ovvio no-no ...

Sì, è possibile farlo fatto utilizzando tale codice. ma il codice non si applicano quando quando a è globale (un programma gcc-compilato mi ha dato segmentation fault.)

In linea generale, in amata C, si può quasi sempre trovare qualche modo per incidere le cose che non dovrebbero essere cambiate o esposti. const qui è un esempio.

ma pensando il povero ragazzo (forse io dopo 6 mesi) mantiene il nostro codice, spesso non si sceglie di farlo.

Qui il tipo di puntatore p è int*, che viene assegnato il valore di tipo const int* (&a => indirizzo di una variabile const int).

Cast implicito elimina la costanza, anche se gcc lancia un avvertimento (si prega di notare che questo dipende in gran parte l'attuazione).

Dato che il puntatore non è dichiarata come const, il valore può essere modificato utilizzando tale puntatore.

se il puntatore sarebbe stata dichiarata come const int* p = &a, non sarà in grado di fare *p = 70.

Non è possibile modificare il valore di una variabile costante utilizzando un puntatore che punta ad esso. Questo tipo di puntatore è chiamato come Pointer to a constant.

C'è anche un altro concetto chiamato Constant Pointer. Ciò significa che una volta che un puntatore punta a una posizione di memoria non si può fare riferimento al percorso all'altro.

Bad, cattiva idea.

Inoltre, il comportamento è piattaforma e implementazione specifici. Se siete in esecuzione su una piattaforma in cui la costante è memorizzato in una memoria non-scrivibile, questo ovviamente non funzionerà.

E, perché sulla terra si vorrebbe? Aggiornare il costante nella vostra fonte, o renderlo una variabile.

Il codice contiene un violazione di vincolo :

const int a = 12;
int *p;
p = &a;

Il vincolo violato è C11 6.5.16.1/1 "Assegnazione semplice"; se entrambi gli operandi sono puntatori quindi il tipo puntata dalla sinistra deve avere tutte le qualificazioni del tipo puntata da destra. (E i tipi, sans qualificazioni, deve essere compatibile).

Quindi, il vincolo è violato perché &a ha tipo const int *, che ha const come qualificatore; ma che qualificatore non compare nel tipo di p che è int *.

Il compilatore deve emettere una diagnosi e non potrebbe generare un eseguibile. Il comportamento di qualsiasi eseguibile sarebbe completamente indefinito, dal momento che il programma non è conforme con le regole della lingua.

Sì, è possibile modificare il valore di una variabile costante.
Prova questo codice:

#include <stdio.h>

int main()
{
    const  int x=10;

    int *p;
    p=(int*)&x;
    *p=12;
    printf("%d",x);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top