C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

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

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French)
View previous topic :: View next topic  
Author Message
Marc Boyer
Guest





PostPosted: Wed Apr 21, 2004 8:57 am    Post subject: char const * const argv[] vs char const *argv[] vs char* ar Reply with quote



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...
Back to top
Antoine Leca
Guest





PostPosted: Wed Apr 21, 2004 10:39 am    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote



En c65d17$7hd$1 (AT) news (DOT) cict.fr, Marc Boyer va escriure:
Quote:
Ni gcc ni g++ n'acceptent la conversion char* argv[] en const char*
argv[].

La déclaration "correcte" est
char * const argv[]

<DIGRESSION>
Pour des raisons de compatibilité avec l'existant, l'officielle n'a pas le
const. Mais la norme C dans son texte refuse l'autorisation de modifier les
éléments du tableau: 5.1.2.2.1p2, en partie:

-- The parameters *argc* and *argv* and the strings pointed to by the
*argv* array shall be modifiable by the program, and retain their last-
stored values between program startup and program termination.

Par élimination, tout est modifiable, sauf les éléments du tableau argv
original. Autrement sit, si tu veux modifier les éléments de argv[], il faut
d'arbord copier le tableau ailleurs, faire les modifications que tu veux, et
ensuite réaffecter argv vers ta copie locale.
</DIGRESSION>

GCC C (et probablement GCC C++), dans son infinie grandeur, te laisse sans
broncher faire des conversions de argv vers un char *[], pour la même raison
que la norme: compatibilité avec l'existant qui ne coannaitr pas les
bienfaits de const. Mais à partir du moment où il y a un const dans le type,
GCC C devient féroce, et refuse de convertir un tableau non modifiable
(argv) en tableau modifiable (ton paramètre), même si dans le même temps tu
augmentes la contrainte sur les éléments pointés (modifiables selon la
norme, non modifiés selon ton prototype).

D'autre part, il y a la tentative d'augmenter la contrainte sur les chaînes
pointées. Ici, je pense que C et C++ divergent, donc tout ce que j'écris
peut ne pas être vrai en C++.

En C, donc, la règle sur const signifiant "ne sera pas modifié" s'applique
uniquement au paramètre lui-même, pas aux composants à partir desquels est
construit son type.

Détail: 6.3.2.2/6.5.2.2 Function calls, par. 2, en partie:
Each argument shall have a type such that its value may be assigned to
an object with the unqualified version of the type of its corresponding
parameter.

Ce qui renvoie vers les affectations: 6.3.16.1/6.5.16.1 Simple assignment,
par.1, en partie:
- both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;

Il faut donc s'en remettre aux règles de compatibilité de types pour voir si
on peut ajouter des qualificateurs sur les sous-éléments. Et là, surprise,
si tu changes les qualificateurs, ce n'est plus compatible: 6.5.4.1/6.7.5.1
Pointer declarators, par.2:
For two pointer types to be compatible, both shall be identically
qualified and both shall be pointers to compatible types.

Ce qui explique les râleries de GCC C.


Antoine


Back to top
Jean-Marc Bourguet
Guest





PostPosted: Wed Apr 21, 2004 2:38 pm    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote




Je ne suis pas sur de ce qu'est ton probleme (en particulier prends tu
argc/argv pour l'illustrer ou bien les parametres de main sont parties
du problemes?). Si c'est simplement comme illustration du probleme de
conversion entre types pointeurs de pointeurs avec des qualifications
const/volatile differentes:

Les regles C++ telles que je m'en souviens sont:

- si a un niveau, la source a un const, alors la destination doit
l'avoir aussi; de meme pour volatile

- si a un niveau, la destination a un const et la source pas, alors
la destination doit avoir un const a tous les niveaux precedants

Exemple de ce que la deuxieme regle veut eviter:

int main() {
char const c = 'c';
char* pc;
char const** pcc = &pc; // interdit
*pcc = &c;
*pc = 'C'; // modifie c
}

(suivi sur fr.comp.lang.c++, je ne traite que du C++ et ne sais pas si
les regles sont differentes en C)

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Back to top
Marc Boyer
Guest





PostPosted: Wed Apr 21, 2004 2:59 pm    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote

In article <c65j3e$td8$1 (AT) shakotay (DOT) alphanet.ch>, Antoine Leca wrote:
Quote:
En c65d17$7hd$1 (AT) news (DOT) cict.fr, Marc Boyer va escriure:
Ni gcc ni g++ n'acceptent la conversion char* argv[] en const char*
argv[].

La déclaration "correcte" est
char * const argv[]

Dans le cas qui motive mon questionnement, je reproduis les memes
messages d'erreur en subsituant toto a main dans le code.
Mais je saute quand meme sur la digression.
Quote:

DIGRESSION
Pour des raisons de compatibilité avec l'existant, l'officielle n'a pas le
const. Mais la norme C dans son texte refuse l'autorisation de modifier les
éléments du tableau: 5.1.2.2.1p2, en partie:

-- The parameters *argc* and *argv* and the strings pointed to by the
*argv* array shall be modifiable by the program, and retain their last-
stored values between program startup and program termination.

Par élimination, tout est modifiable, sauf les éléments du tableau argv
original. Autrement sit, si tu veux modifier les éléments de argv[], il faut
d'arbord copier le tableau ailleurs, faire les modifications que tu veux, et
ensuite réaffecter argv vers ta copie locale.

En fait, dans l'usage immediat que j'en vois, ca permet de modifier l'ordre
des parametres, pour, par exemple, mettre les options au debut de la ligne
de commande et se faciliter l'analyse).

Quote:
/DIGRESSION

[SNIP]
Mais à partir du moment où il y a un const dans le type,
GCC C devient féroce, et refuse de convertir un tableau non modifiable
(argv) en tableau modifiable (ton paramètre), même si dans le même temps tu
augmentes la contrainte sur les éléments pointés (modifiables selon la
norme, non modifiés selon ton prototype).

Sauf que meme si j'ecris
int toto(int argc, char* argv[])
c'est pareil ;-0

Quote:
D'autre part, il y a la tentative d'augmenter la contrainte sur les chaînes
pointées. Ici, je pense que C et C++ divergent, donc tout ce que j'écris
peut ne pas être vrai en C++.

Je sens en effet des divergences (ce qui m'a pousse a un crosspost,
m'obligeant a forcer la main a mon lecteur de news)

Quote:
En C, donc, la règle sur const signifiant "ne sera pas modifié" s'applique
uniquement au paramètre lui-même, pas aux composants à partir desquels est
construit son type.

La, je seche... Prenons
void foo(const char* s)
qu'est-ce que le parametre ( s ?) et son type c'est char* ou const char* ?

Quote:
Détail: 6.3.2.2/6.5.2.2 Function calls, par. 2, en partie:
Each argument shall have a type such that its value may be assigned to
an object with the unqualified version of the type of its corresponding
parameter.

unqualified == pas de const ?
si le type c'est char const * const, le unqualified, c'est
char const * ou char* ?

Plus je relis les paragraohes que tu cites, plus ca me semble
crucial dans la comprehension.

Quote:
Ce qui renvoie vers les affectations: 6.3.16.1/6.5.16.1 Simple assignment,
par.1, en partie:
- both operands are pointers to qualified or unqualified versions of
compatible types, and the type pointed to by the left has all the
qualifiers of the type pointed to by the right;

Il faut donc s'en remettre aux règles de compatibilité de types pour voir si
on peut ajouter des qualificateurs sur les sous-éléments. Et là, surprise,
si tu changes les qualificateurs, ce n'est plus compatible: 6.5.4.1/6.7.5.1
Pointer declarators, par.2:
For two pointer types to be compatible, both shall be identically
qualified and both shall be pointers to compatible types.

Ce qui explique les râleries de GCC C.

Heuh... J'ai pas tout saisi la...

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...

Back to top
Horst Kraemer
Guest





PostPosted: Wed Apr 21, 2004 3:10 pm    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote

On 21 Apr 2004 08:57:11 GMT, Marc Boyer
<Marc.Boyer (AT) enseeiht (DOT) yahoo.fr.invalid> wrote:

Quote:
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...

Je ne comprends plus ce que tu ne comprends pas ;-)

Il n'y pas de conversion automatique char** vers const char** parce
que la norme le dit Wink On en a déjà parlé ici plusieurs fois.


Un exemple qui montre qu'une conversion automatique ne serait pas sure

const char *cc = "hello world!";

void foo(const char **pp)
{
*pp = cc;
}

char *p;
foo(&p); /* si c'était légal on pourrait */
p[0]="H"; /* dévier un char* sur une chaîne constante. */

...oops.....


--
Horst


Back to top
Marc Boyer
Guest





PostPosted: Wed Apr 21, 2004 3:44 pm    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote

Horst Kraemer wrote:
Quote:
On 21 Apr 2004 08:57:11 GMT, Marc Boyer
[email]Marc.Boyer (AT) enseeiht (DOT) yahoo.fr.inva[/email]lid> wrote:

Il n'y pas de conversion automatique char** vers const char** parce
que la norme le dit Wink On en a déjà parlé ici plusieurs fois.

Oui, mais j'avais piscine ;-)

Quote:
Un exemple qui montre qu'une conversion automatique ne serait pas sure

const char *cc = "hello world!";

void foo(const char **pp)
{
*pp = cc;
}

char *p;
foo(&p); /* si c'était légal on pourrait */
p[0]="H"; /* dévier un char* sur une chaîne constante. */

...oops.....

OK, je note, j'imprime, je sauve et je le me tatoue dans la main.

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 ?

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...

Back to top
Marc Boyer
Guest





PostPosted: Wed Apr 21, 2004 4:24 pm    Post subject: Re: char const * const argv[] vs char const *argv[] vs char Reply with quote

Jean-Marc Bourguet wrote:
Quote:
Les regles C++ telles que je m'en souviens sont:

- si a un niveau, la source a un const, alors la destination doit
l'avoir aussi; de meme pour volatile

- si a un niveau, la destination a un const et la source pas, alors
la destination doit avoir un const a tous les niveaux precedants

Oui, ok, la notion de précédence étant sur les niveaux
d'indirection. OK.

Quote:
Exemple de ce que la deuxieme regle veut eviter:

int main() {
char const c = 'c';
char* pc;
char const** pcc = &pc; // interdit
*pcc = &c;
*pc = 'C'; // modifie c
}

OK.

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...

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (French) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.