Question Pointeur vers un tableau avec un qualificatif const en C & C ++


Envisagez le programme suivant:

int main()
{
    int array[9];
    const int (*p2)[9] = &array;
}

Il compile bien en C ++ (voir la démo en direct ici) mais échoue dans la compilation en C. Par défaut, GCC donne les avertissements suivants. (Voir la démo en direct ici).

prog.c: In function 'main':
prog.c:4:26: warning: initialization from incompatible pointer type [enabled by default]
     const int (*p2)[9] = &array;

Mais si j'utilise -pedantic-errors option:

gcc -Os -s -Wall -std=c11 -pedantic-errors -o constptr constptr.c

il me donne suite erreur de compilation

constptr.c:4:26: error: pointers to arrays with different qualifiers are incompatible in ISO C [-Wpedantic]

Pourquoi il échoue dans la compilation en C mais pas en C ++? Que dit la norme C & C ++ à ce sujet?

Si j'utilise const qualificatif dans la déclaration de déclaration de tableau qu'il compile bien dans C également. Alors, que se passe-t-il ici dans le programme ci-dessus?


17
2017-12-28 06:15


origine


Réponses:


GCC-gnu

Dans GNU C, les pointeurs vers les tableaux avec des qualificateurs fonctionnent de manière similaire aux pointeurs vers les autres types qualifiés. Par exemple, une valeur de type int (*)[5] peut être utilisé pour initialiser une variable de type const int (*)[5]. Ces types sont incompatibles dans ISO C parce que le const qualificateur est formellement attaché au type d'élément du tableau et non le tableau lui-même.

C standard dit que (section: §6.7.3 / 9):

Si la spécification d'un type de tableau inclut des qualificateurs de type, le type d'élément est qualifié, pas le type de tableau. [...]

Regardez maintenant le standard C ++ (section § 3.9.3 / 5):

[...] Les qualificatifs Cv appliqués à un type de tableau attachent au type d'élément sous-jacent, donc la notation "cv T," où T est un type de tableau, fait référence à un tableau dont les éléments sont qualifiés. Un type de tableau dont les éléments sont qualifiés cv est également considéré comme ayant les mêmes qualifications CV que ses éléments. [ Exemple:

 typedef char CA[5];
 typedef const char CC;
 CC arr1[5] = { 0 };
 const CA arr2 = { 0 };

Le type des deux arr1 et arr2 est "Tableau de 5 caractères const" et le type de tableau est considéré comme const-qualifié. -Endexample]

Par conséquent, l'initialisation

const int (*p2)[9] = &array;  

est l'affectation de type pointeur vers le tableau [9] de int à pointeur vers le tableau [9] de const int. Ce n'est pas similaire à l'affectation int * à un const int * où const est appliqué directement à la type d'objet le pointeur pointe sur. Ce n'est pas le cas avec const int(*)[9] où, en C, const est appliqué aux éléments de l'objet tableau au lieu de l'objet sur lequel pointe le pointeur. Cela rend l'initialisation ci-dessus incompatible.

Cette règle est modifiée en C ++. Comme const est appliqué à l'objet tableau lui-même, l'affectation se fait entre les mêmes types pointeur vers le tableau const [9] de int au lieu de type pointeur vers le tableau [9] de int et pointeur vers le tableau [9] de const int.


21
2017-12-28 06:38