#include <stdio.h>
void print_vertical(char *str) ;
int main(int argc, char *argv[])
{
if (argc > 1)
print_vertical(argv[1]) ;
return 0 ;
}
void print_vertical(char *str)
{
while (*str)
printf("%c\n", *str++) ;
}
Merci
Ça ressemble à un exercice...
Que se passe-t-il lorsque tu passes un paramètre (en ligne de commande)
à ton programme ?...
Ham
Oops, j'ai oublié de mettre le lien du code que j'ai copié-collé (il
n'y a aucun commentaire qui va avec le code et je suis autodidacte,
c'est pourquoi je cherche à comprendre :
http://www.java2s.com/Code/C/Function/Passcharpointerintofunction.htm
...
Quand je passe un paramètre, je modifie la valeur retournée par une
fonction. Maintenant, je ne sais pas ce que c'est que passer un
paramètre en ligne de commande. Je devrais avoir 10/20 si c'était un
exercice?
La ligne de commande c'est ce qu'on �crit sur le prompt d'un shell
quelconque (je te vois venir, c'est quoi un shell ? c'est quoi un
prompt ?), en g�n�ral batch (fen�tre DOS), ou bash (fen�tre Cygwin ou
Xterm linux).
http://maraudeur.virtuaboard.com/tutoriels-f18/linux-qu-est-ce-qu-une-ligne-de-commande-t250.htm
Donc si tu compiles un programme qui te donne un ex�cutable toto, la
ligne de commande c'est
./toto param1 param2 param3 ...
Et les param�tres sont r�cup�r�s dans le tableau argv[ ] sous forme de
string, et argc en donne le nombre + 1 (argv[0] �tant en g�n�ral le
nom du programme appel�).
http://www.cmi.univ-mrs.fr/~contensi/coursC/index.php?section=env&page=comm
--
zwim.
Rien n'est impossible que la mesure de la volont� humaine...
Je n'avais pas encore vu cette partie du langage c. Par curiosité, les
variables de la ligne de commande sont stockées en mémoire?
Directement dans un ou des registres?
Merci
La ligne de commande et le passage de paramètres n'est pas une
particularité du langage C mais de de ton système (en fait de la
partie qui appelle les application, souvent un 'shell').
Ce qui est propre au langage C, c'est la manière (décrite ci-dessus)
pour récupérer les données de la ligne de commande.
> variables de la ligne de commande sont stockées en mémoire?
Si tu parles des données, oui, elle sont stockée en mémoire, mais
qu'importe. Ce qui compte c'est de savoir qu'elle sont de classe
'static', c'est à dire permanente pendant la durée d'exécution du
programme. Elles appartiennent au processus courant.
Embrouillons, embrouillons ...
>> variables de la ligne de commande sont stock�es en m�moire?
>
> Si tu parles des donn�es, oui, elle sont stock�e en m�moire, mais
> qu'importe.
Bonne r�ponse.
> Ce qui compte c'est de savoir qu'elle sont de classe
> 'static',
Les param�tres de la ligne de commande sont de classe static ?????
Et t'as vu �a au cin�ma ?
> Elles appartiennent au processus courant.
Embrouillons, embrouillons toujours, chargeons encore un peu la barque
avant qu'elle ne coule ...
Le bon code : sandbox.
Pourquoi � embrouillons � ? Surtout que tu as coup� l'autre phrase
d'Emmanuel, qui expliquait ce qui est propre au langage C, c'est-�-dire
le concept de tableau argv[*] pr�d�coup�.
Qui plus est, Emmanuel n'est pas rentr� dans les d�tails des diff�rents
syst�mes de passage de param�tres ; car la ligne de commande n'est qu'un
syst�me comme un autre, avec Unix tu peux utiliser execxx() � la place,
avec les environnements graphiques ce sera une icone etc.; on s'en
moque, c'est le boulot du compilateur de faire la transition pour
pr�senter des arguments d�coup�s.
>> Ce qui compte c'est de savoir qu'elle sont de classe
>> 'static',
>
> Les param�tres de la ligne de commande sont de classe static ?????
Tu n'as pas lu le texte que tu as coup� ?
Les param�tres de la ligne de commande sont un concept ext�rieur.
On parle donc uniquement des arguments pass�s par l'environnement
d'ex�cution C � la fonction main()).
Les arguments (les valeurs) pass�s au programme dans le tableau argv,
ainsi que leur nombre argc (les noms des param�tres sont des
conventions), sont effectivement des variables de dur�e de stockage
statique, c'est-�-dire ni automatique ni dynamique. Il est facile de
comprendre que ce ne peut �tre dynamique (tu ne peux pas �crire
free(argv[0]) ou utiliser realloc). Et la derni�re contrainte de
5.1.2.2.2a2 (� ... gardent leurs valeurs [...] pendant la terminaison du
programme. �) les exempt de pouvoir avoir la dur�e automatique de main.
Antoine
Pour faire simple :
argc contient le nombre de paramètres passés à ton programme (ligne de
commande ou autre) + 1.
argv est un tableau de argc chaînes de caractères représentant les
paramètres passés à ton programme, plus le nom du fichier exécutable qui
contient ton programme (dans argv[0]).
Donc les paramètres passés à ton programme sont stockés dans argv[1],
argv[2]...argv[argc]
Maintenant, si tu exécutes ton programme avec un paramètre, tu pourras
déduire facilement le fonctionnement de la fonction print_vertical (en
fait tu pouvais déjà le déduire au nom de cette foncton).
Ham
C'est vrai que pour commencer, autant faire simple sans trop rentrer
dans les détails techniques. Les questions plus pointues lui viendront
après ça et de nombreuses erreurs de sa part ;)
Ham
> Donc les paramètres passés à ton programme sont stockés dans argv[1],
> argv[2]...argv[argc]
... argv[argc-1], non ?
--
LL
Euh, oui.
Ham, ridiculisé ;)
> Pourquoi � embrouillons � ?
Parce qu'il embrouille le PO. Et bien que -ed- soit un autodidacte, il
manque franchement d'empathie.
> Surtout que tu as coup� l'autre phrase
La suite tu veux dire ? oui, je ne l'ai pas cit� car l'embrouille dont
je parle n'est pas l�.
> d'Emmanuel, qui expliquait ce qui est propre au langage C, c'est-�-dire
"expliquait" est un bien grand mot pour un commentaire aussi court,
vague et abstrait que celui qu'il donne et qui de toute fa�on n'arrive
pas � prendre en compte la probl�matique gloabale du PO. Probl�me
d'empathie r�current chez -ed- ...
(le PO, c'est qui ? oui, c'est toi : bpascal123)
> le concept de tableau argv[*] pr�d�coup�.
Il n'explique rien d'aussi pr�cis, il fait un discours vague que le PO
est incapable d'assimiler. Et je n'ai rien coup�, j'ai juste dit que son
pseudo recadrage n'avait qu'un effet de surcharge (--> embrouille)
>
> Qui plus est, Emmanuel n'est pas rentr� dans les d�tails des diff�rents
> syst�mes de passage de param�tres ;
Encore heureux, il aurait �t� encore plus embrouillant. Mais je sais
qu'il peut l'�tre.
> car la ligne de commande n'est qu'un
> syst�me comme un autre, avec Unix tu peux utiliser execxx() � la place,
> avec les environnements graphiques ce sera une icone etc.; on s'en
> moque, c'est le boulot du compilateur de faire la transition pour
> pr�senter des arguments d�coup�s.
>
Faut m�me pas parler de tout �a � un d�butant comme le PO.
>
>
>>> Ce qui compte c'est de savoir qu'elle sont de classe
>>> 'static',
>> Les param�tres de la ligne de commande sont de classe static ?????
>
> Tu n'as pas lu le texte que tu as coup� ?
Aucun rapport, -ed- r�pond � autre chose
> Les param�tres de la ligne de commande sont un concept ext�rieur.
Oui et non. La Norme elle-m�me parle de la ligne de commande (m�me si
elle n'utilise par ce terme) donc ce n'est pas un concept totalement
"ext�rieur".
> On parle donc uniquement des arguments pass�s par l'environnement
> d'ex�cution C � la fonction main()).
Mais on s'en fout de �a. Essaye de regarder comment le PO voit les
choses. Pour lui, la ligne de commande c'est du C, r�ponds lui en C. Il
a pas besoin de savoir que la ligne de commande existe au niveau syst�me
sinon il va penser qu'il faut connaitre tout le syst�me, tous les
syst�mes, avant d'apprendre le C.
>
> Les arguments (les valeurs) pass�s au programme dans le tableau argv,
> ainsi que leur nombre argc (les noms des param�tres sont des
> conventions), sont effectivement des variables de dur�e de stockage
> statique, c'est-�-dire ni automatique ni dynamique.
1�) Chapitres et versets ?
2�) Que ce soit vrai ou pas, c'�tait une r�ponse inadapt� au niveau
av�r� du PO.
Alors on attend toujours ta réponse adaptée... Car tu critiques
beaucoup mais tu ne proposes toujours rien ...
Tel que nous connaissons bpascal123 depuis plusieurs mois, le silence
�tait une r�ponse plus adapt�e que ton verbiage technique (et qui en
outre est probablement faux : j'attends tes citations de la Norme ou
celles d'Antoine) et de toutes fa�ons compl�tement incompr�hensible de
la part du PO.
bpascal123 a besoin d'un recadrage complet, un tel recadrage ne tient
pas dans une r�ponse technique herm�tique (ou pas) et un forum tel que
celui-ci n'y est pas adapt�.
> #include <stdio.h>
> void print_vertical(char *str) ;
> int main(int argc, char *argv[])
> {
> � �if (argc > 1)
> � � � � � �print_vertical(argv[1]) ;
> � �return 0 ;
> }
> void print_vertical(char *str)
> {
> � �while (*str)
> � � � � � �printf("%c\n", *str++) ;
> }
[...]
>...
>Quand je passe un param�tre, je modifie la valeur retourn�e par une
>fonction. Maintenant, je ne sais pas ce que c'est que passer un
>param�tre en ligne de commande. Je devrais avoir 10/20 si c'�tait un
>exercice?
ce paragraphe n'a aucun sens. Tu as des petits soucis de vocabulaire.
On va preciser un peu.
Si tu es "dans" ton programme C, tu as des fonctions telles que:
void f(int a)
{
...
}
En C, les passages de parametres se font toujours par valeur. Avec les
type de base du langage (tel que int), tu ne peux rien "modifier" en
passant un parametre a une fonction.
Comme le C est un langage procedural classique, les fonctions ne sont pas
des fonctions au sens mathematique usuel: elles peuvent avoir des "effets
de bord". Typiquement:
void f(int a)
{
printf("%d\n", a);
}
Lorsque tu appelles f, tu ecris un truc comme
f(5);
mathematiquement, il ne se passe rien (5 n'est pas modifie, heureusement, et
f ne renvoie rien), MAIS f est quand meme utile: elle affiche 5 sur la sortie.
C'est ca qu'on appelle un effet de bord.
Si tu veux une interaction directe entre tes fonctions et ton programme, il
te faut des fonctions qui renvoient un truc.
Par exemple:
int square(int n)
{
return n * n;
}
et dans ton programme principal:
b = square(15);
par exemple. Juste histoire de fixer les idees.
Maintenant, cette histoire de passer des parametres a ton programme.
La fonction main() a un statut particulier, puisque c'est la ou ton programme
demarre.
En C standard, la fonction main() admet deux declarations valides (ton
systeme peut admettre d'autres declarations, qui doivent etre documentees,
mais ce n'est plus du C standard);
int main()
ou
int main(int argc, char *argv[])
Tu as l'habitude du premier cas: tu communiques avec le systeme par le biais
des entrees-sorties, le systeme te permettant de recuperer des trucs au
clavier et d'afficher des trucs a l'ecran. Plus precisement, tu as deux fichiers
ouverts a disposition: stdin et stdout. stdin en lecture, et stdout en
ecriture. scanf() marche avec stdin, printf() avec stdout et par defaut,
ces deux "fichiers" sont connectes a ton clavier et ton ecran.
(j'emploie le terme fichier de maniere un peu flou... c'est pas necessairement
des vrais fichiers sur disque, mais juste des trucs sur lesquels tu peux
faire des entrees-sorties).
Il existe une autre facon d'interagir avec le systeme: les parametres passes
au lancement du programme. Je ne sais pas du tout ce que tu utilises comme
systeme/compilateur/ide, mais tu dois pouvoir dire au lancement du programme
"oh ben, je voudrais passer des parametres a mon programme" (peut-etre
les options d'une entree "executer" dans ton ide, peut-etre des proprietes
de la jolie icone qui te permet d'executer ton programme).
Traditionnellement, sous Unix, on tape plein de trucs. Typiquement, on
ouvre un terminal, et le systeme te donne un interpreteur de commande.
Pour executer un programme compile (appelle monprog), on tape alors:
monprog
si on veut rajouter des choses, on peut taper:
monprog p1 p2
C'est a ca que sert la 2e forme de main: argv[] est un tableau de chaines
de caracteres, et le systeme te les remplit, a raison d'un mot par case
(les mots etant betement separes par des espaces). argc te donne la taille
du tableau... A l'arrivee, on aura ici:
argv[0] = "monprog";
argv[1] = "p1";
argv[2] = "p2";
argc = 3;
Nota bene 1: le nom du programme se retrouve egalement dans argv... en fait,
on a tout ce qui a ete tape dans l'interpreteur de commande qui se retrouve
dans argv.
Nota bene 2: Unix et C sont tres tres lies. C est ne en meme temps qu'Unix,
a ete ecrit par les memes personnes. Il y a pas mal de choses dans le
langage qui font pleinement du sens sous Unix. Typiquement, argv est une
notion qui est fortement liee a la ligne de commande. En principe, ton
environnement de developpement DOIT te permettre de "faire la meme chose",
donc de "passer des parametres en ligne de commande" a ton programme, meme
si tout est une interface graphique.
Nota bene 3: dans pas mal d'environnements graphiques, tu auras d'autres
prototypes valides pour main(). Mais ca sort du cadre de ce newsgroup (qui
traite du C standard). Tu peux trouver ce genre d'info dans la doc de
ton environnement de developpement, ou en allant fouiller sur un newsgroup
plus approprie a ton systeme...
Il n'y pas pire sourd que celui qui ne veut pas entendre.
>
>
> Tel que nous connaissons bpascal123 depuis plusieurs mois, le silence
> �tait une r�ponse plus adapt�e que ton verbiage technique (et qui en
> outre est probablement faux : j'attends tes citations de la Norme ou
> celles d'Antoine) et de toutes fa�ons compl�tement incompr�hensible de
> la part du PO.
>
> bpascal123 a besoin d'un recadrage complet, un tel recadrage ne tient
> pas dans une r�ponse technique herm�tique (ou pas) et un forum tel que
> celui-ci n'y est pas adapt�.
>
Bravo, heureusement qu'il existe des personnes capable de discernement.
Franchement, en l'occurrence c'est un peu aussi lui qui l'a cherch�, en
changeant de th�me en plein milieu d'un fil:
<news:ee2a7255-0ac8-4b29...@r5g2000yqb.googlegroups.com>
Re: Que doit-on attendre de ce code ?
: Je n'avais pas encore vu cette partie du langage c. Par curiosit�, les
: variables de la ligne de commande sont stock�es en m�moire?
: Directement dans un ou des registres?
Par contre, Emmanuel aurait d� changer le sujet du fil.
> "expliquait" est un bien grand mot pour un commentaire aussi court,
> vague et abstrait que celui qu'il donne et qui de toute fa�on n'arrive
> pas � prendre en compte la probl�matique gloabale du PO. Probl�me
> d'empathie r�current chez -ed- ...
Je ne comprend pas pourquoi tu cherches absolument � faire taire
Emmanuel, m�me si tu lui diagnostiques un manque d'empathie.
>> Qui plus est, Emmanuel n'est pas rentr� dans les d�tails des diff�rents
>> syst�mes de passage de param�tres ;
<mini-snip>
> Faut m�me pas parler de tout �a � un d�butant comme le PO.
<snip>
> Mais on s'en fout de �a.
Cela signifie-t-il que ce sujet est tabou (dans ce groupe ou dans ce fil) ?
Antoine
La norme parle (5.1.2.2.1) de cha�nes fournies � partir de
l'environnement par l'impl�mentation. Pas vu de concept de ligne (qui
impliquerait une certaine unit�) � ce niveau.
� moins que j'ai loup� une partie de ton argument, dans ce cas je te
remercie de me donner quelques pistes.
>> On parle donc uniquement des arguments pass�s par l'environnement
>> d'ex�cution C � la fonction main()).
>
> Mais on s'en fout de �a.
Mmmm... d�sol�, mais je ne suis pas totalement d'accord.
Tu �cris que pour toi, les � param�tres de la ligne de commande � sont
tout sauf de � classe statique � ; je suis de l'avis d'Emmanuel sur ce
point (au vocabulaire pr�s), donc je me permets d'expliquer pourquoi je
pense qu'il a raison d'�crire cela.
> Essaye de regarder comment le PO voit les choses.
J'ai pris le soin de changer le titre du fil, justement parce que je
pense que le posteur initial ne va pas suivre (et n'a pas vraiment
besoin) cette discussion.
>> Les arguments (les valeurs) pass�s au programme dans le tableau argv,
>> ainsi que leur nombre argc (les noms des param�tres sont des
>> conventions), sont effectivement des variables de dur�e de stockage
>> statique, c'est-�-dire ni automatique ni dynamique.
>
> 1�) Chapitres et versets ?
Je suis extr�mement d�sol� pour m'�tre tromp� d'un dans ma citation
<news:heok7j$fj7$1...@shakotay.alphanet.ch>, au dernier paragraphe.
La r�f�rence corecte est le chapitre 5, paragraphe 5.1.2.2.1, 2e alin�a.
� 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.
Pour les dur�es de stockage: 6.1.2.4/6.2.4 Storage durations of objects,
en particulier le 2e/3e alin�a.
Tu remarqueras que les _arguments_ pass�s au programme ne sont ni nomm�s
ni m�me (explicitement) d�clar�s, d'o� le raisonnement de mon message
pr�cv�detn, que je ne vais pas r�p�ter ; il ne faut �videmment pas les
confondre avec les _param�tres_ (nomm�s conventionnellement argc et
argv) de la fonction main, qui peuvent �tre tr�s diff�rents, par exemple
en cas d'appel r�cursif � la fonction main.
Antoine
>
> La norme parle (5.1.2.2.1) de chaînes fournies à partir de
> l'environnement par l'implémentation. Pas vu de concept de ligne
Oui, c'était une façon de parler, "ligne de commande" est le raccourci
habituel pour parler des arguments de main().
> Mmmm... désolé, mais je ne suis pas totalement d'accord.
> Tu écris que pour toi, les « paramètres de la ligne de commande » sont
> tout sauf de « classe statique » ; je suis de l'avis d'Emmanuel sur ce
> point (au vocabulaire près), donc je me permets d'expliquer pourquoi je
> pense qu'il a raison d'écrire cela.
>
>
>> 1°) Chapitres et versets ?
>
> Je suis extrêmement désolé pour m'être trompé d'un dans ma citation
> <news:heok7j$fj7$1...@shakotay.alphanet.ch>, au dernier paragraphe.
> La référence corecte est le chapitre 5, paragraphe 5.1.2.2.1, 2e alinéa.
> — 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.
T'en fais pas j'avais lu et relu tout le paragraphe concernant "la ligne
de commande"
>
> Pour les durées de stockage: 6.1.2.4/6.2.4 Storage durations of objects,
> en particulier le 2e/3e alinéa.
Oui, je l'ai lu et relu.
> Tu remarqueras que les _arguments_ passés au programme ne sont ni nommés
> ni même (explicitement) déclarés,
J'avais remarqué ce point en effet.
> d'où le raisonnement de mon message
> précvédetn, que je ne vais pas répéter ;
J'ai pas vu un message précédent où tu fais un raisonnement relatif à
"la ligne de commande" (si tu pouvais citer le lien http de
groups.google plutôt que le liens <new&###!15744154584uiydgbciu...>
auquel je comprends rien ;) )
> il ne faut évidemment pas les
> confondre avec les _paramètres_ (nommés conventionnellement argc et
> argv) de la fonction main, qui peuvent être très différents, par exemple
> en cas d'appel récursif à la fonction main.
Oui, j'ai bien saisi la nuance.
Maintenant discutons du sexe des anges. Sur le fond, Emmanuel et toi
avez probablement raison. D'une certaine façon, les arguments de la
ligne de commande sont de "classe" (ce n'est pas le terme de la Norme)
"static". Ils partagent avec ce type d'objet le fait que leur durée de
vie est celle du programme et qu'ils sont alloués avant le début de son
exécution. Néanmoins, la Norme ne le dit pas formellement. Cela tient à
mon avis au statut particulier de ces objets : ils ne sont pas alloués
par le programme mais par l'environnement. En fait il y a 4 objets :
-- argc (fourni par l'environnement)
-- la copie de argc passé en argument à main() (les arguments sont
passés par valeur),
-- argv
-- les chaînes pointées dans le "tableau" argv .
J'aurais tendance à dire que argc et argv sont de classe automatique et
seules les chaînes pointées sont de classe statique. Mais la Norme ne
dit rien. Pourtant, dans un autre cas similaire où le programme alloue
un objet sans le déclarer, celui des chaînes littérales, la Norme prend
bien soin de préciser que les chaînes sont de classe statique.
Par ailleurs, il y a une autre difficulté : la Norme ne donne pas
précisément la définition de la "classe" static, ni d'"automatic" ni
même d'"allocated" (rien de formel en tous cas). Elle dit d'abord qu'il
existe trois types de durée de mémorisation. Ensuite, elle dit que dans
telle ou telle circonstance tel objet est de classe statique, en général
à la déclaration de l'objet sauf, comme je l'ai dit ci-dessus, pour les
chaînes littérales. Voilà pourquoi j'ai trouvé abusif de qualifier les
arguments de la ligne de commande de classe statique bien
qu'effectivement ils en ont les caractéristques. Mais à la limite, je ne
vois pas où la Norme m'empêcherait de considérer que les arguments du
programme (les chaînes) sont de classe automatique !!
>J'aurais tendance à dire que argc et argv sont de classe automatique et
>seules les chaînes pointées sont de classe statique. Mais la Norme ne
>dit rien. Pourtant, dans un autre cas similaire où le programme alloue
>un objet sans le déclarer, celui des chaînes littérales, la Norme prend
>bien soin de préciser que les chaînes sont de classe statique.
C'est pas exactement comme ca que ca fonctionne, c'est pour ca que ta norme
ne te dit rien. Sur les implementations usuelles, ton programme ne commence
pas dans main(), mais sur un autre symbole, souvent __start, qui va faire
des choses pour s'arranger pour t'appeler main (appelons-le __start pour
simplifier).
Sur certaines implementations, c'est __start qui te fabrique argc et argv
a la mano (j'en ai deja croise, ou le systeme te fournit une bete chaine de
caracteres, et ou c'est __start qui te la decoupe en petits mots).
Sur d'autres, ca peut etre l'appel systeme, par exemple execve,
qui lance le programme qui te fait le boulot. Appelons-le execve.
Donc a l'arrivee, argc et argv peuvent etre dans une zone memoire de meme
nature que tes chaines litterales (c'est une bonne idee si le systeme
le permet), ou peuvent etre de betes variables locales propres a __start, avec
de betes malloc/free (ou equivalents) pour l'allocation des chaines
correspondantes (voire du alloca si ton systeme en a un. Vu que c'est pas
cense etre du code portable, anything goes).
C'est un peu pour ca que c'est tres flou. :-)
Si j'ai bonne memoire, c'est d'ailleurs un petit point de difference entre
C et C++. Il me semble que la norme C++ donne un statut tres particulier
a main(), qui n'est vraiment pas une fonction comme les autres, et qu'en
particulier tu ne peux pas la rappeler de l'interieur de ton programme...
> Si j'ai bonne memoire, c'est d'ailleurs un petit point de difference
> entre C et C++. Il me semble que la norme C++ donne un statut tres
> particulier a main(), qui n'est vraiment pas une fonction comme les
> autres, et qu'en particulier tu ne peux pas la rappeler de l'interieur de
> ton programme...
Confirm�.
A+
--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Recette à toute épreuve, partant par exemple de
<news:heok7j$fj7$1...@shakotay.alphanet.ch>
On lance son navigateur
Dans la barre d'adresses, on tape groups.google.com/groups?selm=
On découpe à la souris le message-id, heok7j$fj7$1...@shakotay.alphanet.ch
On colle le message-id derrière le selm=
On tape entrée
On lit
Antoine
Attention : ils ne sont pas alloués au sens de la norme.
Sinon, ce n'est pas vraiment l'environnement (qui n'est pas spécifié),
mais une partie de l'implémentation (nommée /program startup/ dans le
norme, et correspondant historiquement à une bonne part d'un fichier
objet passé à l'éditeur des liens en tout début de liste des arguments)
L'objet désigné par errno est dans la même catégorie.
> En fait il y a 4 objets :
> -- argc (fourni par l'environnement)
> -- la copie de argc passé en argument à main() (les arguments sont
> passés par valeur),
> -- argv
> -- les chaînes pointées dans le "tableau" argv .
Si on accepte que le « argv » dans ton énumération ci-dessus désigne le
paramètre (un pointeur vers tableau de chaînes) passé en argument à
main(), par le même mécanisme que pour « la copie de argc », il te
manque le "tableau" lui-même (construit à partir de l'environnement).
> J'aurais tendance à dire que argc et argv sont de classe automatique et
Voui. Mais je ne veux pas parler de ceux-là (d'où mon appréciation
qu'Emmanuel a utilisé une mauvaise formulation au départ).
> seules les chaînes pointées sont de classe statique.
C'est là où je ne suis pas d'accord. Pour moi le premier terme ci-dessus
ainsi que le tableau (le 5e article) sont aussi de classe statique.
Je lis 5.1.2.2.1§2 dernier alinéa comme
> Mais la Norme ne dit rien.
??? Au seul endroit où elle mentionne les chaînes, elle mentionne les
deux autres objets...
> Pourtant, dans un autre cas similaire où le programme alloue
> un objet sans le déclarer, celui des chaînes littérales, la Norme prend
> bien soin de préciser que les chaînes sont de classe statique.
Bzzz. « prend bien soin » est une lecture erronée de la norme.
Cette norme est en construction permanente : si des demandes
d'interprétation ou des rapports de défaut sont jugés suffisament
sérieux pour amener à de possibles malentendus sur la signification, le
comité rajoute du texte pour rendre le sujet limpide. Il ne faut donc
RIEN dériver de l'absence de texte précis sur un point, mais bien au
contraire prendre une lecture globale et tenter d'interpréter les
différents éléments. Si une seule explicaition est possible (et si elle
concorde avec la pratique), c'est la bonne ; si tu arrives à plusieurs
explications possibles (par exemple, s'il est possible de mettre les
littéraux chaînes sur la pile), il faut demander une interprétation car
il y a probablement un défaut ; et si tru arrives à une seule
explication MAIS que la pratique diffère, là tu es sûr qu'il y a un
défaut (ou cas plus probable à l'heure actuelle, tu t'es trompé quelque
part).
> Par ailleurs, il y a une autre difficulté : la Norme ne donne pas
> précisément la définition de la "classe" static, ni d'"automatic" ni
> même d'"allocated" (rien de formel en tous cas). Elle dit d'abord qu'il
> existe trois types de durée de mémorisation.
Il faut surtout comprendre que c'est une partition. C'est très évident
si tu remarques qu'au départ, la norme C89 ne mentionnait que les deux
premières, et que la troisième fut rajoutée suite à un commentaire, car
les objets créés par malloc() ne collent pas à la classse statique en
terme, justement, de /durée/ de vie.
> Mais à la limite, je ne vois pas où la Norme m'empêcherait de
> considérer que les arguments du programme (les chaînes) sont de
> classe automatique !!
Bien justement, parce que le fameux dernier alinéa de 5.1.2.2.1
explicite que les chaînes doivent être encore valides dans la "program
termination" (donc tu peux les utiliser dans une fonction atexit() après
avoir sauvegarder un pointeur vers un de ces chaînes dans une variable
globale).
Antoine
J'ai employ� ce terme en me croyant autoris� � le faire : la Norme ne
l'emploi pas dans un sens uniforme : au d�part, c'est une des dur�es de
m�morisation ("allocated storage duration") mais par la suite le terme
s'applique aussi � des tableaux ou des structures, exemple :
As discussed in 6.2.5, a structure is a type consisting of a sequence of
members, whose storage is allocated in an ordered sequence
>
> Sinon, ce n'est pas vraiment l'environnement (qui n'est pas sp�cifi�),
OK (note que le titre de la Partie 6 est "Environnement").
>
>
>> En fait il y a 4 objets :
>> -- argc (fourni par l'environnement)
>> -- la copie de argc pass� en argument � main() (les arguments sont
>> pass�s par valeur),
>> -- argv
>> -- les cha�nes point�es dans le "tableau" argv .
>
> Si on accepte que le � argv � dans ton �num�ration ci-dessus d�signe le
> param�tre (un pointeur vers tableau de cha�nes) pass� en argument �
> main(), par le m�me m�canisme que pour � la copie de argc �, il te
> manque le "tableau" lui-m�me (construit � partir de l'environnement).
>
Oui
>
>> J'aurais tendance � dire que argc et argv sont de classe automatique et
>
> Voui. Mais je ne veux pas parler de ceux-l� (d'o� mon appr�ciation
> qu'Emmanuel a utilis� une mauvaise formulation au d�part).
>
>> seules les cha�nes point�es sont de classe statique.
>
> C'est l� o� je ne suis pas d'accord. Pour moi le premier terme ci-dessus
> ainsi que le tableau (le 5e article) sont aussi de classe statique.
>
> Je lis 5.1.2.2.1�2 dernier alin�a comme
>
>> Mais la Norme ne dit rien.
>
> ??? Au seul endroit o� elle mentionne les cha�nes, elle mentionne les
> deux autres objets...
Oui. Mais je ne vois pas ce que �a prouve. La Norme dit que
"Each parameter has automatic storage duration. "
Au passage je lis un peu plus loin :
"The layout of the storage for parameters is unspecified."
C'est pas contradictoire avec ce qui pr�c�de ?
> Bzzz. � prend bien soin � est une lecture erron�e de la norme.
Oui, mon � prend bien soin � �tait un peu tendancieux ;)
>
>
>> Mais � la limite, je ne vois pas o� la Norme m'emp�cherait de
>> consid�rer que les arguments du programme (les cha�nes) sont de
>> classe automatique !!
>
> Bien justement, parce que le fameux dernier alin�a de 5.1.2.2.1
> explicite que les cha�nes doivent �tre encore valides dans la "program
> termination"
Je sais bien que ce que je vais dire peut para�tre absurde mais si je me
fie juste au texte de la Norme qu'est-ce que �a contredit le fait de
supposer que les cha�nes soient de classe automatique puisque lorsque
lorsque le bloc qui d�finit main(), mon programme se termine et donc mes
cha�nes s'�vanouissent ?
Non. Elle sont statiques, elles persistent au retour de main() car
main() n'est ni le d�but ni la fin du programme.
Je crois que plus concr�tement, il y a un cas o� �a changerait
quelque-chose pour le programmeur : atexit(). Si main() se termine par
return x (mais pas exit()), c'est l'environnement qui appellera exit(x)
APRES le retour de main() (5.1.2.2.3 n'explique pas ce m�canisme de
mani�re tr�s claire, il part du principe que return x ou exit(x), c'est
kif-kif, mais voir plus bas). Au final, exit() est toujours appel� une
fois, que ce soit manuellement ou automatiquement, et lui-m�me appelle
tous les myExit() enregistr�s avec atexit().
Ce qui veut dire que le programmeur peut reprendre le contr�le apr�s le
retour de main() et avant le nettoyage complet (vidage et fermeture des
flux, qui justement peuvent encore �tre utiles pour signaler un �ventuel
probl�me d�tect� � la sortie).
Si on consid�rait que les cha�nes de argv �taient automatiques, elles
n'existeraient plus � la sortie de main() et un myExit() qui les lirait
serait largu�. Ca peut para�tre tir� par les cheveux, car a priori �a
n'est pas le meilleur endroit pour traiter des arguments, mais je ne
m'attendrais pas � ce qu'un objet dit statique ne soit plus disponible
dans myExit() de toutes fa�ons.
Sinon, voir le rationale 7.20.4.3 :
...
Aside from calls explicitly coded by a programmer, exit is invoked on
return from main. Thus in at least this case, the body of exit cannot
assume the existence of any objects with automatic storage duration
except those declared in exit.
...
Ce qui n'est gu�re plus clair � premi�re vue (je suis loin d'�tre un
sp�cialiste de la bible), mais je ne vois qu'un truc du genre
exit(main(...)) (je sch�matise hein) cot� appelant pour expliquer le
fait que les automatiques seraient compromis dans les cas o� exit()
n'est pas appel� explicitement par le programmeur.
Enfin, un snip de Dinkumware accessible en ligne, plus limpide sur une
impl�mentation possible de tout ce blabla (et qui correspond plut�t �
l'id�e que je m'en faisais) :
========================================================================
*If main returns to its caller, the target environment calls exit with
the value returned from main as the status argument to exit*. If the
return statement that the program executes has no expression, the status
argument is undefined. This is the case if the program executes the
implied return statement at the end of the function definition.
You can also call exit directly from any expression within the program.
In both cases, exit calls all functions registered with atexit in
reverse order of registry *and then begins program termination*.
At program termination, the target environment closes all open files,
removes any temporary files that you created by calling tmpfile, and
then returns control to the invoker, using the status argument value to
determine the termination status to report for the program.
========================================================================
--
Alex
Tu ne sch�matises rien du tout ! Si tu regardes le code de crt0.c (quand
il est �crit en C), tu as de grandes chances d'y lire
exit(main(_argc, _argv, _environ));
_argc et _argv sont les deux objets /statiques/ (les noms peuvent
varier, en particulier certains ont rajout� des soulign�s en t�te pour
faire plus �inaccessibles�) dont nous parlons depuis le d�but.
Je sais bien qu'une (ou plusieurs) impl�mentation n'est pas une preuve
de la norme, mais cela montre que ta lecture est bonne.
Antoine
Je n'ai aucune pr�tention � te l'interdire. De fait, tu as raison de
pr�ciser que "allocated" est un terme passablement surcharg� dans le
texte de la norme.
Je cherchais seulement � attirer l'attention des lecteurs sur le fait
que la dur�e de stockage n'est pas "allocated".
>>> Mais la Norme ne dit rien.
>> ??? Au seul endroit o� elle mentionne les cha�nes, elle mentionne les
>> deux autres objets...
>
> Oui. Mais je ne vois pas ce que �a prouve. La Norme dit que
>
> "Each parameter has automatic storage duration. "
>
> Au passage je lis un peu plus loin :
>
> "The layout of the storage for parameters is unspecified."
>
> C'est pas contradictoire avec ce qui pr�c�de ?
Non, � partir du moment o� on comprend que argc et argv sont les
_param�tres_ (des objets automatiques) qui sont diff�rents des
_arguments_ (qui n'ont pas de noms d�finis par la norme).
Tu as toi m�me �tabli une liste de 4 ou 5 objets qui montre cette
distinction.
Si tu relis le paragraphe sur les appels de fonction, tu verras que
l'association entre argument et param�tre (une assignation) se fait au
moment de l'appel, et par la suite chacun vit sa vie. De ce fait, en C
les param�tres ne sont pas const, et il y a pas mal de programmes qui
profitent de ce fait et (ab)usent de param�tre comme si c'�tait une
variable locale suppl�mentaire. �videmment, l'argument, de son c�t�,
reste intact tel qu'il �tait au moment de l'appel.
Antoine
Continuons notre "chicken or egg discussion"
Antoine Leca a �crit :
> candide �crivit :
>> Antoine Leca a �crit :
>>> candide �crivit :
>> Oui. Mais je ne vois pas ce que �a prouve. La Norme dit que
>>
>> "Each parameter has automatic storage duration. "
>>
>> Au passage je lis un peu plus loin :
>>
>> "The layout of the storage for parameters is unspecified."
>>
>> C'est pas contradictoire avec ce qui pr�c�de ?
>
> Non, � partir du moment o� on comprend que argc et argv sont les
> _param�tres_ (des objets automatiques) qui sont diff�rents des
> _arguments_ (qui n'ont pas de noms d�finis par la norme).
>
Il n'y a pas d'arguments car c'est ainsi que la Norme les d�finit :
argument actual argument actual parameter (deprecated) expression in the
comma-separated list bounded by the parentheses in a function call
expression, or a sequence of preprocessing tokens in the comma-separated
list bounded by the parentheses in a function-like macro invocation
Le probl�me est que dans le cas de la fonction main(), sauf appel
r�cursif direct ou indirect, il n'y a pas d'appel du genre
main(42, vers_mes_chaines)
comme pour une fonction "classique"
f(42)
La Norme ne dit pas que c'est comme si on faisait
main(42, vers_mes_chaines)
mais elle dit juste :
The intent is to supply to the program information determined prior to
program startup from elsewhere in the hosted environment.
("The intent", bof, pas tr�s pr�cis)
> Si tu relis le paragraphe sur les appels de fonction, tu verras que
> l'association entre argument et param�tre (une assignation) se fait au
> moment de l'appel, et par la suite chacun vit sa vie.
Bien s�r, c'est le principe du passage par valeur (mais ici il n'y a pas
d'appel main(42, toto)). Ici justement, l'objet donn� par
l'environnement vit sa vie (et sa mort aux yeux du programme C puisqu'il
ne peut plus communiquer avec lui) et pour le programme C, seul existe
l'objet param�tre donn� � main().
Pendant qu'on y est, puisqu'on a �voqu� la question, comment
comprends-tu la phrase :
"The layout of the storage for parameters is unspecified."
"unspecified" c'est je suppose au sens de l'annexe J1. Mais qu'est-il
entendu par "layout". C'est quand m�me pas une histoire de "pile" ou de
"tas" puisque la Norme ne connait pas ces mots-l� ? Ou alors �a veut
dire qu'on ne peut faire aucune supposition par exemple que les objets
seraient stock�s avec des adresses qui seraient dans l'ordre
d'apparition dans la liste des d�clarations des param�tres ?
Ma lecture des trois premiers mots du paragraphe 5.1.2.2.1 m'incite �
penser le contraire. Mais je n'arriverais pas � te convaincre, donc je
ne vais m�me pas essayer.
> Pendant qu'on y est, puisqu'on a �voqu� la question, comment
> comprends-tu la phrase :
>
> "The layout of the storage for parameters is unspecified."
Que la norme ne r�glemente pas (au-del� des autres contraintes existant
par ailleurs) comment les param�tres sont organis�s dans l'espace
d'adressage, ou dans des registres, s'ils sont align�s ou pas, se
recouvrent, etc.
> "unspecified" c'est je suppose au sens de l'annexe J1.
Plut�t 3.4.4 �MHA.
> Mais qu'est-il entendu par "layout".
� Disposition � ?
Cela devient peut-�tre plus clair si tu lis les propos du /Rationale/
(p. 96) � ce sujet : il y est expliqu� en particulier que pour les
fonctions variadyques comme printf, la m�thode utilis�e par <varargs.h>
n'�tait pas suffisamment portable et devait �tre �vit�e dans des
programmes portables.
Antoine
Le mot "function called" est employ� certes mais pas au sens de
"function call" qui suppose un appel avec l'op�rateur ().
>
>> Mais qu'est-il entendu par "layout".
>
> � Disposition � ?
Oui, je connais le sens du mot layout mais dans ce contexte, �a ne me
semblait pas tr�s pr�cis ni tr�s clair.
>
> Cela devient peut-�tre plus clair si tu lis les propos du /Rationale/
Ah oui, j'avais pas pens� � regarder
> (p. 96) � ce sujet : il y est expliqu� en particulier que pour les
> fonctions variadyques comme printf, la m�thode utilis�e par <varargs.h>
> n'�tait pas suffisamment portable et devait �tre �vit�e dans des
> programmes portables.
Ah OK, merci de ta r�ponse.