web-dev-qa-db-fra.com

Est-ce que "const" signifie juste en lecture seule ou quelque chose de plus?

Que signifie vraiment const? La lecture seule semble résumer sa signification pour moi, mais je ne suis pas sûre d'avoir raison.

Si en lecture seule et const sont différents, quelqu'un pourrait-il me dire pourquoi?

La question qui a motivé cette question était cette réponse où il déclare const "juste" signifie en lecture seule en C. Je pensais que cela voulait dire allconst, que ce soit en C ou C++. Que veut-il dire?

Pour répondre aux différences spécifiques entre const en C et C++, j'ai créé une nouvelle question: En quoi "const" diffère-t-il en C et C++? Selon la suggestion de R. ...

29
Kim Sun-wu

En déclarant une variable en tant que const, vous indiquez au compilateur que vous n’avez aucune intention de modifier cette variable. Mais cela ne signifie pas que les autres n'en ont pas! C'est juste pour permettre une optimisation et être averti par une erreur de compilation (notez qu'il s'agit principalement d'une erreur de compilation, alors que const == ReadOnly signifierait des erreurs d'exécution).

const ne signifie pas en lecture seule, car vous pouvez écrire const volatile, cela signifierait que il pourrait changer par lui-même à tout moment, mais je n'ai pas l'intention de le modifier.

EDIT: voici un exemple classique: considérez que j’écris le code qui lit l’heure actuelle à partir d’un port mappé en mémoire. Considérez que RTC est associé à la mémoire DWORD 0x1234.

const volatile DWORD* now = (DWORD*)0x1234;

C'est const parce que c'est un port en lecture seule, et c'est volatile car chaque fois que je le lirai, cela changera.

Notez également que de nombreuses architectures rendent effectivement les variables globales déclarées comme étant const en lecture seule, car il est UB de les modifier. Dans ces cas, UB se manifestera par une erreur d'exécution. Dans d'autres cas, ce serait un vrai UB :)

Voici une bonne lecture: http://publications.gbdirect.co.uk/c_book/chapter8/const_and_volatile.html

45
ruslik

Le compilateur n'autorisera pas la modification de quelque chose déclaré comme const. C'est comme tu dis.

Il est principalement utilisé dans les prototypes de fonctions pour informer l'utilisateur qu'une fonction ne touchera pas ceci ou cela lorsque des pointeurs seront transmis. Cela fonctionne aussi comme une sorte de sécurité intégrée pour vous-même.

7
slezica

Beaucoup de gens vous disent que const signifie que vous ne pouvez pas le modifier. C'est manifestement faux. const peut être trivialement jeté. Notez cet extrait:

void foo(const int *somevalue)
{
   int *p = (int*) somevalue;
   *p = 256;  // OMG I AM EVIL!!!!11
}

Votre compilateur ne vous empêchera pas de le faire. Alors, quel est le but de const? Je l'appellerais plus d'une suggestion. Cela vous rappelle que vous examinez les prototypes de fonctions du contrat que vos fonctions attendent. Votre compilateur va crier après vous si vous le casser négligemment. (Mais pas si vous le cassez intentionnellement, comme avec la distribution ci-dessus.)

Dans certains cas, la norme rompt intentionnellement const. Notez les valeurs de retour de strstr par exemple: par définition, il retournera un certain décalage dans le tampon const que vous le fournissez ... Mais la valeur renvoyée n'est pas const. Pourquoi? Eh bien, cela serait rompu de manière significative en utilisant la valeur de retour de strstr sur un tampon non -const.

2
asveikau

Deux octets pour octet identique (à l'exception des commentaires), exemples de cas minimaux ... 

D'abord en C, gcc émettra un avertissement ...

/* Fonction prenant un pointeur sur un tableau de 
 deux entiers en lecture seule. */
 void a (const int (* parray) [2]); 

 void b (void) 
 {
 int array [2] = {1,2}; 
 const int crray [2] = {1,2}; 
/* C se réserve le droit de conserver cette information dans un emplacement en lecture seule. */

 un (& tableau); 
/* warning: passer l’argument 1 de ‘a’ à partir d’un type de pointeur incompatible */
 un (& crray); /* D'ACCORD!*/
}

Maintenant, la même chose en C++ ... g ++ en est assez content.

 // Fonction prenant un pointeur sur un tableau 
 // de deux entiers qu’elle ne promet pas de modifier. 
 // (Sauf si nous rejetons sa constance ;-P) 
 Void a (const int (* parray) [2]); 

 Void b (void) 
 {
 int array [2] = {1,2}; 
 const int crray [2] = {1,2}; 

 un (& tableau); // C++ n'a pas de problème avec ceci .
 un (& crray); // D'ACCORD!
}
1
John Carter
const char * hello_1{ "Hello!" };
const char   hello_2[]{ "Hello!" };
char       * ptr{};

// take away the const-nes
// ptr = (char *)hello_1;
// *ptr = '*'; <-- write access violation
// hello_1 is in a read only memory

// take away the const-nes
ptr = (char *)hello_2;
*ptr = '*'; // <-- OK
// hello_2 is modifiable

Les pointeurs pointent vers la mémoire et char * pointe vers la mémoire dans le segment de données qui est en lecture seule. La différence entre char * et char [] est que, bien que les deux soient déclarés de la même manière sur le segment de données, char [] est considéré comme lisible, car il est poussé dans la pile s'il est utilisé.

0
user5560811