Domanda

Mentre ricevo il mio codice rivisto qui il problema dell'utilizzo di const è venuta fuori la parola chiave.Capisco che viene utilizzato per implementare il comportamento di sola lettura sulle variabili.

Sono confuso su quali siano le varie situazioni in cui può essere utile.

  • Dovrebbe essere utilizzato per motivi di chiarezza nei prototipi di funzioni?
  • Dovrebbe essere utilizzato come misura di sicurezza durante lo sviluppo del codice?
  • Dovrebbe essere utilizzato nell'ambito di varie funzioni per dichiarare le costanti di runtime?
  • Dovrebbe essere utilizzato?

Queste domande sono solo esempi della confusione che sto affrontando.La confusione generale è

  • Quando dovrebbe essere il const parola chiave utilizzata nella programmazione C?
  • Quali sono i vari tipi di vantaggi che si possono ottenere utilizzando questa parola chiave in C?
  • Ci sono degli svantaggi nell'usarlo const parola chiave?


È stato sottolineato che questa domanda potrebbe essere troppo ampia a causa di tutte queste domande nel dettaglio della mia domanda.Volevo solo chiarire che queste domande servono solo a chiarire la confusione riguardo alla questione principale.

Quando e per quali scopi dovrebbe essere utilizzata la parola chiave const in C per le variabili?

Può anche essere riformulato come

Il corretto utilizzo di const parola chiave in C` con i pro e i contro della stessa.

È stato utile?

Soluzione

Durante la revisione del codice, applico le seguenti regole:

  • Usalo sempre const Per i parametri della funzione passati per riferimento in cui la funzione non modifica (o libera) i dati indicati.

    int find(const int *data, size_t size, int value);
    
  • Usalo sempre const per costanti che potrebbero altrimenti essere definite utilizzando un #define o un enum.Di conseguenza, il compilatore può individuare i dati nella memoria di sola lettura (ROM) (sebbene il linker sia spesso uno strumento migliore per questo scopo nei sistemi embedded).

    const double PI = 3.14;
    
  • Non utilizzare mai const in una funzione prototipo per un parametro passatovalore.Non ha significato ed è quindi solo "rumore".

    // don't add const to 'value' or 'size'
    int find(const int *data, size_t size, int value); 
    
  • Laddove appropriato, utilizzare const volatile su posizioni che non possono essere modificate dal programma ma che potrebbero comunque cambiare.I registri hardware sono il caso d'uso tipico in questo caso, ad esempio un registro di stato che riflette lo stato di un dispositivo:

    const volatile int32_t *DEVICE_STATUS =  (int32_t*) 0x100;
    

Altri usi sono facoltativi.Ad esempio, i parametri di una funzione all'interno della funzione implementazione può essere contrassegnato come const.

// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)  
{
     ... etc

o la funzione restituisce valori o calcoli ottenuti e quindi non cambiano mai:

char *repeat_str(const char *str, size_t n) 
{
    const size_t len = strlen(str);
    const size_t buf_size = 1 + (len * n);
    char *buf = malloc(buf_size);
    ...

Questi usi di const indica semplicemente che non modificherai la variabile;non cambiano come o dove viene archiviata la variabile.Il compilatore può ovviamente capire che una variabile non viene modificata, ma aggiungendo const gli permetti di imporlo.Questo può aiutare il lettore e aggiungere un po 'di sicurezza (anche se se le tue funzioni sono abbastanza grandi o complicate da fare una grande differenza, probabilmente hai altri problemi). Modifica - ad es.Una funzione densamente codificata a 200 linee con loop nidificati e molti nomi di variabili lunghi o simili, sapendo che alcune variabili non cambiano mai potrebbero facilitare la comprensione in modo significativo.Tali funzioni sono state progettate o mantenute.


Problemi con const.Probabilmente sentirai il termine "avvelenamento costante".Ciò si verifica durante l'aggiunta const a una funzione parametro fa propagare la "costiness".

Modifica - avvelenamento costante:ad esempio nella funzione:

int function_a(char * str, int n)
{
    ...
    function_b(str);
    ...
}

se cambiamo str A const, dobbiamo quindi garantirlo fuction_b prende anche un const.E così via se function_b passa il str su function_c, eccetera.Come puoi immaginare, questo potrebbe essere doloroso se si propaga in molti file/moduli separati.Se si propaga in una funzione che non può essere modificata (ad esempio una libreria di sistema), diventa necessario un cast.Quindi spolverataconst in giro nel codice esistente forse è in cerca di guai.Nel nuovo codice, però, è meglio const qualificarsi in modo coerente, ove appropriato.

Il problema più insidioso di const è che non era nella lingua originale.Come componente aggiuntivo non è del tutto adatto.Per cominciare ha due significati (come nelle regole sopra, il che significa che "non cambierò questo" e "questo non può essere modificato").Ma soprattutto, può essere pericoloso.Ad esempio, compilare ed eseguire questo codice e (a seconda del compilatore/opzioni) potrebbe essere arrestato quando si esegue:

const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '\0';

strchr restituisce a char* non un const char*.Come lo è il suo parametro di chiamataconst deve lancio il parametro di chiamata a char*.E in questo caso che getta via la vera proprietà di archiviazione di sola lettura. Modificare:- questo si applica generalmente alle variabili nella memoria di sola lettura.Per "ROM" intendo non solo la ROM fisica ma qualsiasi memoria protetta da scrittura, come accade alla sezione di codice dei programmi eseguiti su un tipico sistema operativo.

Molte funzioni della libreria standard si comportano allo stesso modo, quindi attenzione:quando hai vero costanti (es.Conservato in ROM) Devi stare molto attento a non perdere la loro costine.

Altri suggerimenti

Generally in any programming language its recommended to use const or the equivalent modifier since

  • It can clarify to the caller that what they passed in is not going to change
  • Potential speed improvements since the compiler knows for certain it can omit certain things that are only relevant if the parameter can change
  • Protection from yourself accidentally changing the value

In agreement with TheLQ's statements:

When working with a team of programmers declaring const is a good way of indicating that said variable shouldn't be modified, or just for reminding yourself in large projects. It's useful in that sense, and can save many headaches.

Yes, it's basically the TheLQ's answer.

Is a security measure for the programmer so you don't modify a variable, and to not call functions that may modify them. In an array or structure the const specifier indicates that the values of their contents won't be modified, and even the compiler will not allow you to do so. You still can easily change the value of the variable with just a cast however.

In what I have usually see, it's mostly used to add constant values in code, and to indicate that the array or structure won't be modified if you call a particular function. This last part is important, because when you call a function that WILL modify your array or structure, you may want to keep the original version, so you create a copy of the variable and then pass it to function. If that is not the case, you don't require the copy, obviously, so for example you can change,

int foo(Structure s);

to

int foo(const Structure * s);

and not getting the copy overhead.

Just to add, note that C has particular rules with the const specifier. For example,

int b = 1;
const int * a = &b;

is not the same as

int b = 1;
int * const a = &b;

The first code won't allow you to modify a. In the second case, the pointer is constant but its contents is not, so the compiler will allow you to say * a = 3; without a compiler error, but you can't make a to be a reference to another thing.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top