const type qualifier
Chaque type individuel dans le
système de types
du C possède plusieurs versions
qualifiées
de ce type, correspondant à un, deux ou l'ensemble des trois qualificateurs
const
,
volatile
, et, pour les pointeurs vers des types objet,
restrict
. Cette page décrit les effets du qualificateur
const
.
Les objets déclarés avec des types qualifiés const peuvent être placés en mémoire morte par le compilateur, et si l'adresse d'un objet const n'est jamais prise dans un programme, il peut ne pas être stocké du tout.
Toute tentative de modifier un objet dont le type est qualifié const entraîne un comportement indéfini.
const int n = 1; // objet de type qualifié const int* p = (int*)&n; *p = 2; // comportement indéfini
const
s'applique uniquement aux expressions
lvalue
; chaque fois qu'une expression const lvalue est utilisée dans un contexte qui ne nécessite pas de lvalue, son qualificatif
const
est perdu (notez que le qualificatif volatile, s'il est présent, n'est pas perdu).
Les expressions lvalue qui désignent des objets de type qualifié const et les expressions lvalue qui désignent des objets de type struct ou union avec au moins un membre de type qualifié const (y compris les membres d'agrégats ou d'unions contenus récursivement), ne sont pas des lvalues modifiables . En particulier, elles ne sont pas assignables :
const int n = 1; // objet de type const n = 2; // erreur : le type de n est qualifié const int x = 2; // objet de type non qualifié const int* p = &x; *p = 3; // erreur : le type de la lvalue *p est qualifié const struct {int a; const int b; } s1 = {.b=1}, s2 = {.b=2}; s1 = s2; // erreur : le type de s1 est non qualifié, mais il a un membre const
Un membre d'une structure ou d'un type union qualifié const acquiert la qualification du type auquel il appartient (à la fois lorsqu'il est accédé en utilisant l'opérateur
.
ou l'opérateur
->
).
struct s { int i; const int ci; } s; // le type de s.i est int, le type de s.ci est const int const struct s cs; // les types de cs.i et cs.ci sont tous deux const int
|
Si un type tableau est déclaré avec le qualificatif de type const (via l'utilisation de typedef ), le type tableau n'est pas qualifié const, mais son type d'élément l'est. |
(jusqu'à C23) |
|
Un type tableau et son type d'élément sont toujours considérés comme étant identiquement qualifiés const. |
(depuis C23) |
typedef int A[2][3]; const A a = {{4, 5, 6}, {7, 8, 9}}; // tableau de tableaux de const int int* pi = a[0]; // Erreur : a[0] a le type const int* void *unqual_ptr = a; // OK jusqu'à C23 ; erreur depuis C23 // Notes : clang applique la règle en C++/C23 même dans les modes C89-C17
Si un type de fonction est déclaré avec le qualificatif de type const (via l'utilisation d'un typedef ), le comportement est indéfini.
|
Dans une déclaration de fonction, le mot-clé
Les deux déclarations suivantes déclarent la même fonction : void f(double x[const], const double y[const]); void f(double * const x, const double * const y); |
(depuis C99) |
|
Les littéraux composés qualifiés const ne désignent pas nécessairement des objets distincts ; ils peuvent partager le stockage avec d'autres littéraux composés et avec des littéraux de chaîne qui ont une représentation identique ou chevauchante. const int* p1 = (const int[]){1, 2, 3}; const int* p2 = (const int[]){2, 3, 4}; // la valeur de p2 peut être égale à p1+1 _Bool b = "foobar" + 3 == (const char[]){"bar"}; // la valeur de b peut être 1 |
(depuis C99) |
Un pointeur vers un type non-const peut être implicitement converti en un pointeur vers la version qualifiée const du même type ou d'un type compatible . La conversion inverse nécessite une expression de cast.
int* p = 0; const int* cp = p; // OK : ajoute des qualificateurs (int vers const int) p = cp; // Erreur : supprime des qualificateurs (const int vers int) p = (int*)cp; // OK : cast
Notez qu'un pointeur vers un pointeur vers
T
n'est pas convertible en pointeur vers un pointeur vers
const T
; pour que deux types soient compatibles, leurs qualifications doivent être identiques.
char *p = 0; const char **cpp = &p; // Erreur : char* et const char* ne sont pas des types compatibles char * const *pcp = &p; // OK, ajoute des qualificateurs (char* vers char*const)
Table des matières |
Mots-clés
Notes
C a adopté le qualificateur const de C++, mais contrairement à C++, les expressions de type qualifié const en C ne sont pas des expressions constantes ; elles ne peuvent pas être utilisées comme étiquettes case ou pour initialiser des objets de durée de stockage statique et de durée de stockage thread , énumérateurs , ou tailles de champs de bits . Lorsqu'elles sont utilisées comme tailles de tableaux , les tableaux résultants sont des VLA.
Références
- Norme C17 (ISO/IEC 9899:2018):
-
- 6.7.3 Qualificateurs de type (p: 87-90)
- Norme C11 (ISO/CEI 9899:2011) :
-
- 6.7.3 Qualificateurs de type (p: 121-123)
- Norme C99 (ISO/CEI 9899:1999) :
-
- 6.7.3 Qualificateurs de type (p: 108-110)
- Norme C89/C90 (ISO/IEC 9899:1990) :
-
- 6.5.3 Qualificateurs de type
Voir aussi
|
Documentation C++
pour
les qualificateurs de type cv (
const
et
volatile
)
|