Question

Tout en obtenant mon code examiné ici la question de l'utilisation du const le mot-clé est apparu.Je comprends qu'il est utilisé pour implémenter un comportement en lecture seule sur les variables.

Je ne sais pas quelles sont les différentes situations dans lesquelles cela peut être utile.

  • Doit-il être utilisé par souci de clarté dans les prototypes de fonctions ?
  • Doit-il être utilisé comme mesure de sécurité lors du développement du code ?
  • Doit-il être utilisé dans le cadre de diverses fonctions de déclaration de constantes d'exécution ?
  • Faut-il vraiment l'utiliser ?

Ces questions ne sont que des exemples de la confusion à laquelle je suis confronté.La confusion générale est

  • Quand devrait être le const mot-clé utilisé en programmation C ?
  • Quels sont les différents types d’avantages qui peuvent être obtenus en utilisant ce mot-clé en C ?
  • Y a-t-il des inconvénients à utiliser const mot-clé?


Il a été souligné que cette question pourrait être trop large en raison de toutes ces questions dans le détail de ma question.Je voulais juste préciser que ces questions visent simplement à clarifier la confusion concernant la question principale.

Quand et à quelles fins le mot-clé const doit-il être utilisé en C pour les variables ?

On peut aussi reformuler ainsi

Le bon usage de const mot-clé en C` avec les avantages et les inconvénients de celui-ci.

Était-ce utile?

La solution

Lors de la révision du code, j'applique les règles suivantes :

  • Utilisez toujours const Pour les paramètres de fonction passés par référence lorsque la fonction ne modifie pas (ou libre) les données pointées.

    int find(const int *data, size_t size, int value);
    
  • Utilisez toujours const pour les constantes qui pourraient autrement être définies à l'aide d'un #define ou d'une énumération.Le compilateur peut ainsi localiser les données dans la mémoire morte (ROM) (bien que l'éditeur de liens soit souvent un meilleur outil à cet effet dans les systèmes embarqués).

    const double PI = 3.14;
    
  • N'utilisez jamais const dans une fonction prototype pour un paramètre passé parvaleur.Cela n’a aucune signification et n’est donc qu’un « bruit ».

    // don't add const to 'value' or 'size'
    int find(const int *data, size_t size, int value); 
    
  • Le cas échéant, utilisez const volatile sur des emplacements qui ne peuvent pas être modifiés par le programme mais qui peuvent quand même changer.Les registres matériels constituent le cas d'utilisation typique ici, par exemple un registre d'état qui reflète l'état d'un périphérique :

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

Les autres utilisations sont facultatives.Par exemple, les paramètres d'une fonction au sein de la fonction mise en œuvre peut être marqué comme const.

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

ou la fonction renvoie des valeurs ou des calculs qui sont obtenus et ne changent jamais :

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);
    ...

Ces usages de const indiquez simplement que vous ne modifierez pas la variable ;ils ne changent pas comment ni où la variable est stockée.Le compilateur peut bien sûr déterminer qu'une variable n'est pas modifiée, mais en ajoutant const vous lui permettez de faire respecter cela.Cela peut aider le lecteur et ajouter une certaine sécurité (bien que si vos fonctions sont suffisamment grandes ou compliquées pour que cela fasse une grande différence, vous avez sans doute d'autres problèmes). Modifier - par exemple.Une fonction codée densément à 200 lignes avec des boucles imbriquées et de nombreux noms de variables longs ou similaires, sachant que certaines variables ne changent jamais pour faciliter la compréhension de manière significative.De telles fonctions ont été mal conçues ou maintenues.


Problèmes avec const.Vous entendrez probablement le terme « empoisonnement const ».Cela se produit lors de l'ajout const à un paramètre de fonction fait se propager la «construption».

Modifier - empoisonnement const :par exemple dans la fonction :

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

si nous changeons str à const, il faut alors s'assurer que fuction_b prend également un const.Et ainsi de suite si function_b passe le str sur function_c, etc.Comme vous pouvez l'imaginer, cela pourrait être douloureux s'il se propage dans de nombreux fichiers / modules distincts.S'il se propage en une fonction qui ne peut pas être modifiée (par exemple une bibliothèque système), alors un casting devient nécessaire.Alors saupoudrerconst autour du code existant pose peut-être des problèmes.Dans un nouveau code cependant, il est préférable de const se qualifier de manière cohérente, le cas échéant.

Le problème le plus insidieux de const est que ce n'était pas dans la langue d'origine.En tant que module complémentaire, il ne convient pas tout à fait.Pour un début, il a deux significations (comme dans les règles ci-dessus, ce qui signifie "je ne vais pas changer cela" et "cela ne peut pas être modifié").Mais plus encore, cela peut être dangereux.Par exemple, compiler et exécuter ce code et (en fonction du compilateur / options), il peut bien s'écraser lors de l'exécution:

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

strchr renvoie un char* pas un const char*.Comme son paramètre d'appel estconst il doit casting le paramètre d'appel à char*.Et dans ce cas, cela jette la propriété de stockage en lecture seule. Modifier:- cela s'applique généralement aux variables en mémoire morte.Par «ROM», j'entends non seulement la ROM physique, mais toute mémoire protégée en écriture, comme c'est le cas pour la section de code des programmes exécutés sur un système d'exploitation typique.

De nombreuses fonctions standards de la bibliothèque se comportent de la même manière, alors faites attention :lorsque vous avez réel constantes (c.-à-d.stocké dans Rom) Vous devez faire très attention à ne pas perdre leur construption.

Autres conseils

Généralement, dans n'importe quel langage de programmation, il est recommandé d'utiliser const ou le modificateur équivalent puisque

  • Cela peut clarifier à l'appelant que ce qu'il a transmis ne va pas changer
  • Améliorations potentielles de la vitesse puisque le compilateur sait avec certitude qu'il peut omettre certaines choses qui ne sont pertinentes que si le paramètre peut changer
  • Protection contre vous-même en changeant accidentellement la valeur

En accord avec les déclarations de TheLQ :

Lorsque vous travaillez avec une équipe de programmeurs déclarant const est un bon moyen d'indiquer que ladite variable ne doit pas être modifiée, ou simplement pour se le rappeler dans les grands projets.C’est utile en ce sens et peut éviter de nombreux maux de tête.

Oui, c'est essentiellement la réponse de TheLQ.

C'est une mesure de sécurité pour le programmeur afin de ne pas modifier une variable, et de ne pas appeler de fonctions susceptibles de les modifier.Dans un tableau ou une structure, le spécificateur const indique que les valeurs de leur contenu ne seront pas modifiées, et même le compilateur ne vous permettra pas de le faire.Cependant, vous pouvez toujours facilement modifier la valeur de la variable avec un simple cast.

Dans ce que je vois habituellement, il est principalement utilisé pour ajouter des valeurs constantes dans le code et pour indiquer que le tableau ou la structure ne sera pas modifié si vous appelez une fonction particulière.Cette dernière partie est importante, car lorsque vous appelez une fonction qui VERA modifier votre tableau ou votre structure, vous souhaiterez peut-être conserver la version originale, vous créez donc une copie de la variable puis la transmettez à la fonction.Si ce n'est pas le cas, vous n'avez évidemment pas besoin de la copie, vous pouvez donc par exemple modifier,

int foo(Structure s);

à

int foo(const Structure * s);

et ne pas obtenir la copie en surcharge.

Juste pour ajouter, notez que C a des règles particulières avec le spécificateur const.Par exemple,

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

n'est pas la même chose que

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

Le premier code ne vous permettra pas de modifier un.Dans le deuxième cas, le pointeur est constant mais son contenu ne l'est pas, donc le compilateur vous permettra de dire * a = 3; sans erreur du compilateur, mais vous ne pouvez pas faire a être une référence à autre chose.

Licencié sous: CC-BY-SA avec attribution
scroll top