Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

char const * const argv[] vs char const *argv[] vs char* argv[]

14 réponses
Avatar
Marc Boyer
Je crossposte sur les deux forums C et C++ car le code est
semble dans l'intersection dans languages, meme si la semantique
est peut-etre differente. Que chacun reponde dans le(s) forum(s)
appropries a sa reponse.

Un warning de mon compilateur (gcc 3.3) me fait douter de ma
comprehension de const...

Si je passe un pointeur sur des char a une fonction qui attend
un pointeur sur des char constant, tout va bien (gcc et g++).

Mais quand j'attaque les pointeurs de pointeur (manip de argv),
ca se corse.

Ni gcc ni g++ n'acceptent la conversion char* argv[] en const char* argv[].
Je comprends qu'avec un pointeur de pointeur de char, on peut modifier
l'argument, dans le sens ou on fait pointeur sur "autre chose", mais bon,
si je veux interdire une modif de l'argument, j'ecris
char const * const argv[]
donc deja, je comprends pas trop...

Ensuite, quand je tente la signature char const * const argv[], gcc
continue a raler, mais g++ ne dit plus rien....

Voici un code illustratif de mon incomprehension...

void foo(const char* string);
void barConst(char const * argv[]);
void barConstConst(char const * const argv[]);

int main(int argc, char* argv[]){
char aString[10];
aString[0]= 0;
foo(aString); // OK pour gcc et g++
barConst(argv); // gcc "type pointeur incompatible"
// g++ "conversion invalide de"
barConstConst(argv); // gcc "type pointeur incompatible"
// g++ OK
return 0;
}


Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...

4 réponses

1 2
Avatar
Marc Boyer
Antoine Leca wrote:
En c6685m$dbs$, Marc Boyer va escriure:
Antoine Leca wrote:
Le deuxième const saute en vertu d'une règle spéciale, destinée si
je me rappelle bien à faciliter la compatibilité et l'utilisabilité
de const, en particulier la croyance que « const * pour un paramètre
signifie que la fonction ne modifie pas l'argument », une utile
manière de voir les choses mais la norme n'est pas formulée de cette
manière.


J'avoue avoir présenté le const à mes élèves justement
avec cette idée de non-modification.
Je me demande que leur dire maintenant que le cours
s'attarde sur les pointeurs...


Rien de plus, de toute manière tout le monde utilise const pour cela, ce
n'est pas une mauvaise notion. C'est juste que la norme (C) ne dit pas
exactement cela, et si tu rentres dans ce genre de détails...

Déjà, tes élèves, pour piper ce sujet, il faut qu'ils aient assimilé les
tableaux qui s'amuissent en pointeurs,


Ca a été présenté en long et en travers, on insiste dessus en TD et
en TP, donc, on peut espérer que...

et qu'ils sachent lire de suite le nombre de niveaux de pointeurs.


On va tenter de les y sensibiliser. Les manips sur argv
sont un premier point. On va faire des listes qui sont
des pointeurs de cellule et tout ça.
Après, plus de deux niveaux de pointeurs, ça devient
difficile de trouver des exemples concrets.

Oui, mais j'hésite sur la manière de présenter la chose...
Le coup de "le deuxième const saute pour faire comme
si le const signifiait 'ne modifie pas son paramètre'", je
le sens mal...
En gros, la règle c'est:
- le premier const saute (c'est de toute façon une copie)
- le second, on accepte la conversion non const->const,
pour dire qu'une fonction ne modifie pas son paramètre
- pour les autres, il faut égalité parce que c'est comme
ça


Oui, c'est bien comme cela qu'a été rédigé la norme: ceux qui l'ont rédigé
n'étaient pas convaincus, mais ils sentaient qu'ils devaient faire comme
cela... cf. <URL:http://groups.google.es/groups?selm&97%40cbnewsl.ATT.COM>
(Dave Prosser étant celui qui a rédigé la norme ANSI). Les exemples
démontrant les problèmes concrets sont venus plus tard.


Ca peut toujours faire 2-3 transparents, si un jour
ils ont le probleme et qu'ils ont gardé leur cours..;

Mais je crois que je vais le mettre justement parce que
nombre de bouquins semblent faire l'impasse.

Comme l'explique Jean-Marc ailleurs, certaines choses « sûres » sont
refusées par les règles C (et pas par les règles C++), et en contrepartie
les règles C sont moins complexes à écrire. Au résultat, dans ces cas-là, ce
déclenche un diagnostic en C, mais il n'y a pas de problèmes: le
comportement est clair, sera celui attendu, et les bons compilateurs ne vont
pas être suffisament idiots pour refuser de compiler le programme.


Je ferais une note de bas de page en disant que c'est différent
en C++, et basta.

Marc Boyer

-- La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...



Avatar
kanze
Jean-Marc Bourguet wrote in message
news:...
Marc Boyer writes:

Ceci etant dit, la conversion char** vers char const * const *
elle serait sure dans ce cas (enfin, il me semble).
D'ailleurs, g++ semble l'accepter.
J'ai rate un autre truc ?


g++ l'accepte parce que les regles du C++ sont differentes des regles
du C (voir ). Celles du C sont plus
simples mais interdisent des cas ou la conversion est sans probleme.


C'est plus complex que ça. Au début de la normalisation de C, toutes les
conversions qui ajoutait un const était permis. Vers la fin, quelqu'un
(je ne me rappelle plus qui) a montré l'exemple qui était posté ici
avant, pour signaler que ces conversions n'étaient pas sûr. Alors, C(90)
a modifier la règle, pour fermer le trou.

Lors de la normalisation de C++, quelqu'un a analysé la question plus,
et a bien determiné que la règle C limitait plus que nécessaire. Le C++
a donc adopté une forme plus libérale, qui n'interdit que ce qui est
réelement dangéreux.

Je avais cru que C99 avait adopté les règles C++, mais je ne le trouve
pas dans la norme, et d'après ce que dit Antoine, ça ne semble pas être
le cas. On a donc :

char** p ;
char const** pc = p ; // Illégal dans les deux langages
char const* const *pcc = p ; // Légal en C++, mais non en C

En passant, le type du deuxième paramètre de main est bien char**. La
norme interdit certaines modifications de ce qui est pointé, mais ce
sont des contraints supplémentaires, en dehors du type. Mais tu ne peux
pas légalement affecter argv au une variable qui declare ces contraints
au moyen des const.

Dans les faits, en C++, je copie toujours les paramètres de main dans un
std::vector< std::string >, et j'en fais ce que je veux (légalement). En
C, historiquement, j'ai toujours travaillé « en place » dans argv, en
modifiant les pointeurs. Ce que la norme interdit, mais ce qui marche
avec tous les compilateurs C dont je me suis jamais servi.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


Avatar
Antoine Leca
En c67ujr$n9b$, Marc Boyer va escriure:
Antoine Leca wrote:
et qu'ils sachent lire de suite le nombre de niveaux de pointeurs.


On va tenter de les y sensibiliser. Les manips sur argv
sont un premier point. On va faire des listes qui sont
des pointeurs de cellule et tout ça.
Après, plus de deux niveaux de pointeurs, ça devient
difficile de trouver des exemples concrets.


Le seul cas d'emploi que j'ai jamais rencontré, ce sont les matrices à n
dimensions dans les calculs numériques. Qui justifient probablement un cours
à part, à cause des problèmes pour les passer comme arguments, les allouer,
etc. Plus tard, non ?



Ca peut toujours faire 2-3 transparents, si un jour
ils ont le probleme et qu'ils ont gardé leur cours..;


Hmmmm... L'expérience que j'ai de mes copains, et moi idem, c'est qu'on a
gardé les supports de cours, même (surtout ?) de ceux auxquels nous n'avons
pas assisté, quand le cours était bon. Et même que nous nous les sommes
trimbalés de déménagements en déménagements (les miens ont bien dus faire
3000 km, maintenant ;-)).



Antoine


Avatar
Marc Boyer
Antoine Leca wrote:
En c67ujr$n9b$, Marc Boyer va escriure:
Le seul cas d'emploi que j'ai jamais rencontré, ce sont les matrices à n
dimensions dans les calculs numériques. Qui justifient probablement un cours
à part, à cause des problèmes pour les passer comme arguments, les allouer,
etc. Plus tard, non ?


Le calcul numérique, c'est un domaine à part entière, et on
ne l'aborde pas. On leur fait juste voir les problèmes d'arrondis,
l'égalité entre flottants...

Ca peut toujours faire 2-3 transparents, si un jour
ils ont le probleme et qu'ils ont gardé leur cours..;


Hmmmm... L'expérience que j'ai de mes copains, et moi idem, c'est qu'on a
gardé les supports de cours, même (surtout ?) de ceux auxquels nous n'avons
pas assisté, quand le cours était bon. Et même que nous nous les sommes
trimbalés de déménagements en déménagements (les miens ont bien dus faire
3000 km, maintenant ;-)).


Bon, je vais arrêter de leur demander de venir en cours alors ;-)

Marc Boyer
--
La contractualisation de la recherche, c'est me donner de l'argent pour
faire ce que je ne sais pas faire, que je fais donc mal, pendant que ce
que je sais faire, je le fais sans moyens...


1 2