web-dev-qa-db-fra.com

Y a-t-il const en C?

Cette question peut être naïve, mais:

  • y a-t-il const mot-clé en C?
  • depuis quelle version?
  • existe-t-il des différences sémantiques et/ou syntaxiques entre const en C et C++?
52
Armen Tsirunyan

Il n'y a pas de différences syntaxiques entre C et C++ en ce qui concerne le mot clé const, à part un mot plutôt obscur: en C (depuis C99), vous pouvez déclarer les paramètres de fonction comme

void foo(int a[const]);

ce qui équivaut à

void foo(int *const a);

déclaration. C++ ne prend pas en charge une telle syntaxe.

Des différences sémantiques existent également. Comme @Ben Voigt l'a déjà noté, en C const, les déclarations ne produisent pas d'expressions constantes, c'est-à-dire qu'en C, vous ne pouvez pas utiliser un const int objet dans une étiquette case, comme largeur de champ de bits ou comme taille de tableau dans une déclaration de tableau non VLA (tout cela est possible en C++). De plus, les objets const ont une liaison externe par défaut en C (liaison interne en C++).

Il y a au moins une différence sémantique de plus, que Ben n'a pas mentionnée. Les règles de constance du langage C++ prennent en charge la conversion standard suivante

int **pp = 0;
const int *const *cpp = pp; // OK in C++

int ***ppp = 0;
int *const *const *cppp = ppp; // OK in C++

Ces initialisations sont illégales en C.

int **pp = 0;
const int *const *cpp = pp; /* ERROR in C */

int ***ppp = 0;
int *const *const *cppp = ppp; /* ERROR in C */

En règle générale, lorsqu'il s'agit de pointeurs à plusieurs niveaux, C++ dit que vous pouvez ajouter une qualification const à n'importe quelle profondeur d'indirection, tant que vous ajoutez également une qualification const jusqu'au niveau supérieur.

En C, vous pouvez uniquement ajouter const-qualification au type pointé par le pointeur de niveau supérieur, mais pas plus en profondeur.

int **pp = 0;
int *const *cpp = pp; /* OK in C */

int ***ppp = 0;
int **const *cppp = ppp; /* OK in C */

Une autre manifestation du même principe général sous-jacent est la façon dont les règles de const-correct fonctionnent avec les tableaux en C et C++. En C++, vous pouvez faire

int a[10];
const int (*p)[10] = &a; // OK in C++

Essayer de faire la même chose en C entraînera une erreur

int a[10];
const int (*p)[10] = &a; /* ERROR in C */
55
AnT

Les deux premières questions sont répondues ici: Const en C

Oui, il y a pas mal de différences de sémantique entre const en C et C++.

  • En C++, les variables const de type approprié sont des expressions constantes intégrales (si leurs initialiseurs sont des expressions constantes au moment de la compilation) et peuvent être utilisées dans un contexte qui l'exige, comme les limites des tableaux, et dans les définitions d'énumération. En C, ils ne le sont pas et ne peuvent pas l'être.

  • En C++, les variables globales const ont automatiquement un lien static, vous pouvez donc les placer dans des fichiers d'en-tête. En C, ces variables ont un lien externe et cela générerait des erreurs de définition en double au moment du lien.

13
Ben Voigt

Oui, il existe un mot clé const. Il a été ajouté dans le cadre de la norme de 1989.

En ce qui concerne la compatibilité, voici un paragraphe de Harbison & Steele, 5ème édition:

Une déclaration de niveau supérieur qui a le qualificatif de type const mais aucune classe de stockage explicite n'est considérée comme static en C++ mais extern en C. Pour rester compatible, examinez top- niveau const déclarations et fournir une classe de stockage explicite. En C++, les constantes de chaîne sont implicitement const; ils ne sont pas en C.
8
John Bode

Deux autres différences:

Oui, const existe depuis au moins depuis ANSI C (aka C89).

Il apparaît certainement dans ma copie de "The C Programming Language (2nd Edition)", Kernighan & Ritchie (publié en 1988).

Extrait pertinent:

Les propriétés const et volatile sont nouvelles avec la norme ANSI. Le but de const est d'annoncer les objets qui peuvent être placés en mémoire morte et peut-être d'augmenter les possibilités d'optimisation.

5
GrahamS

Oui. const est là en C, depuis C89.

Voici une bonne lecture qui concerne comportement du mot-clé const en C .

2
Nawaz

La sématique en C est différente de celle en C++, par exemple

unsigned const a = 10;
unsigned A[a];

dans la portée du fichier serait valide en C++ mais pas en C.

2
Jens Gustedt

Il y a un mot-clé "const" en C, et cela depuis longtemps. Si une variable est désignée "const", les écritures y sont interdites. De plus, dans certains environnements, les variables déclarées "const" peuvent se trouver dans un segment de données différent des autres variables. Ce segment de données peut offrir une protection en écriture matérielle, et pour les systèmes embarqués, peut être stocké dans ROM ou mémoire flash plutôt que dans RAM (une distinction très importante sur certains processeurs qui ont beaucoup plus ROM ou flash que RAM - par exemple 128K flash et 3,5K RAM, ou 2K ROM et 96 octets RAM).

Notez que le compilateur va généralement ne pas faire des inférences sur les valeurs "const" ou les expressions les impliquant. Si je dis "const char foo [] =" Bonjour ";" et ensuite faire référence à foo [1], le compilateur chargera la valeur (qui sera très probablement 'e') d'où que foo [] soit stocké et utilisera la valeur chargée. Parfois, cela permet utilement de corriger les valeurs dans une image de code compilé, mais parfois cela gaspille simplement du code.

Si vous voulez définir un nombre comme étant une constante "substituable" au moment de la compilation, la meilleure façon, au moins pour les constantes entières, peut être d'utiliser "enum". Par exemple, "enum {woozle = 19;}" provoquera le remplacement de "woozle" par 19 dans tout le code. Notez que contrairement aux substitutions textuelles; Les déclarations enum obéissent à des règles de portée appropriées.

1
supercat

Oui, il y a un mot clé const en C. Il existe depuis C90.

Syntaxiquement, il peut se produire aux mêmes endroits qu'en C++. Sémantiquement, c'est un peu plus laxiste, IIRC.

1
Anthony Williams

Selon ESR , const a été ajouté dans le projet de norme ANSI C. le résumé d'Eric Giguere sur ANSI C , daté de 1987, le confirme.

EDIT: Cela ressemble au brouillon lui-même - recherchez "3.5.3 Type qualifiers".

1
Ken