prototype de la fonction main : pourquoi argc est il signé ?

Le
hibakusha
Bonjour à tous.

Pour le protoype suivant de main :

int main(int argc, char* argv[])

la norme indique pour argc :

"The value of argc shall be nonnegative."

L'utilisation de "shall" est perturbante, et je me demande ce qu'il
faut comprendre ici : est ce que cela veut bien dire que argc DOIT être
positif ? Et dans ce cas, pourquoi argc est il de type "int", c'est à
dire potentiellement négatif ?

Est ce moi qui comprends mal cette définition, ou bien y a t il la une
bizarerie, héritage quelconque d'un comportement etrange de certaines
version d'unix ou je ne sais quelle autre explication ?

Clairement, je me demande si il existe certaines situations où argc peut
être négatif ?

Et je me pose cette question avant de partir en vacances, c'est un signe

Merci d'apporter vos lumieres sur le sujet

(Je suis sûr que la question à déja été posée, mais je n'arrive pas a
mettre la main sur une réponse)
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #1000088
hibakusha
Bonjour à tous.

Pour le protoype suivant de main :

int main(int argc, char* argv[])

la norme indique pour argc :

"The value of argc shall be nonnegative."

L'utilisation de "shall" est perturbante, et je me demande ce qu'il
faut comprendre ici : est ce que cela veut bien dire que argc DOIT être
positif ?


In this International Standard, shall is to be interpreted as a requirement
on an implementation or on a program; conversely, shall not is to be
interpreted as a prohibition.

Et dans ce cas, pourquoi argc est il de type "int", c'est à dire
potentiellement négatif ?


L'histoire, vraisemblablement.

A+

--
Jean-Marc
FAQ de fclc: http://www.isty-info.uvsq.fr/~rumeau/fclc
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Pascal Bourguignon
Le #1000087
hibakusha
Bonjour à tous.

Pour le protoype suivant de main :

int main(int argc, char* argv[])

la norme indique pour argc :

"The value of argc shall be nonnegative."

L'utilisation de "shall" est perturbante, et je me demande ce qu'il
faut comprendre ici : est ce que cela veut bien dire que argc DOIT être
positif ? Et dans ce cas, pourquoi argc est il de type "int", c'est à
dire potentiellement négatif ?

Est ce moi qui comprends mal cette définition, ou bien y a t il la une
bizarerie, héritage quelconque d'un comportement etrange de certaines
version d'unix ou je ne sais quelle autre explication ?

Clairement, je me demande si il existe certaines situations où argc
peut être négatif ?

Et je me pose cette question avant de partir en vacances, c'est un signe...

Merci d'apporter vos lumieres sur le sujet...

(Je suis sûr que la question à déja été posée, mais je n'arrive pas a
mettre la main sur une réponse)


Tout le monde est d'accord, ce serait mieux si c'était déclaré
unsigned int argc.

Mais le mélange de types entier N-bit non signés et de types entier
N-bit signés en complément à deux est toujours problématique, car les
intervales ne sont pas imbriqués, mais ont une intersection bizarre.

En C, on le voit par les différent warnings qu'un compilateur donne,
et sur les erreurs invisible comises quand on mélange les deux.

En Modula-2, on a un type INTEGER et un type CARDINAL, et c'est à peu
près géré correctement mais ce n'est pas parfait.

En Oberon, le problème est résolu: il n'y a qu'un type signé INTEGER
(et donc, on ne va que jusqu'à 2^(N-1)-1).

En C, tu peux t'amuser d'essayer de mettre du unsigned int partout où
c'est logique. Tu te rendras vite compte que c'est beaucoup plus
simple de mettre partout du int. (C'est comme pour les const, d'ailleurs).


Finalement, le seule language à ma connaissance qui gère ça
correctement, c'est Common Lisp: on peut déclarer des types entiers de
n'importe quelle taille, signé ou non, et les mélanger comme on veut,
et Lisp s'arrange pour obtenir le résultat mathématiquement correct.


--
__Pascal Bourguignon__ http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.

hibakusha
Le #1000086
Pascal Bourguignon wrote:

Tout le monde est d'accord, ce serait mieux si c'était déclaré
unsigned int argc.


ouf, c'est donc bien une bizarerie... dont j'aimerais quand même
connaitre l'origine.

Je suis persuadé qu'il a forcément existé, dans un lointain passé, un
cas très particulier où le système pouvait passé une valeur négative
pour argc, signifiant par là quelque chose de particulier à prendre en
compte.

Ou bien les penseurs-redacteurs de la norme ont imaginé une utilisation
possible en ce sens, ou dans un autre. Et dans ce cas, qu'ont ils imaginé ?

Ou simplement ils se sont dit qu'un jour cela me turlipinera et en ce
moment ils se marrent comme des baleines.

Stephane Legras-Decussy
Le #1000085
"hibakusha" 46bc902c$0$437$
ouf, c'est donc bien une bizarerie... dont j'aimerais quand même connaitre
l'origine.



je ne trouve pas ça bizarre.

perso j'utilise toujours
des variables signées pour des quantités qui ne
peuvent jamais être negatives.

d'ailleur pourquoi les chaines de caractères
sont des char et pas des unsigned char dans ce cas ?
ça devrait te perturber d'avantage...

pour moi les unsigned ne servent que pour des
masques de bit et les operations logiques...

Pierre Maurette
Le #1000084
Bonjour à tous.

Pour le protoype suivant de main :

int main(int argc, char* argv[])

la norme indique pour argc :

"The value of argc shall be nonnegative."

L'utilisation de "shall" est perturbante, et je me demande ce qu'il
faut comprendre ici : est ce que cela veut bien dire que argc DOIT être
positif ? Et dans ce cas, pourquoi argc est il de type "int", c'est à
dire potentiellement négatif ?

Est ce moi qui comprends mal cette définition, ou bien y a t il la une
bizarerie, héritage quelconque d'un comportement etrange de certaines version
d'unix ou je ne sais quelle autre explication ?

Clairement, je me demande si il existe certaines situations où argc peut être
négatif ?

Et je me pose cette question avant de partir en vacances, c'est un signe...

Merci d'apporter vos lumieres sur le sujet...

(Je suis sûr que la question à déja été posée, mais je n'arrive pas a mettre
la main sur une réponse)


1 - Il me semble que l'utilisation de int quand elle est "suffisante"
est privilégiée. C'est le type entier par défaut. Voir la norme (§7.4
?) sur
2 - Il me semble que le "shall" s'adresse plutôt au shell ou au loader
qui va lancer main() dans un "hosted environment" avec les arguments
qui vont bien.

3 - Ce truc-là ne semble pas poser de problème, à part son inutilité
flagrante en l'état:

#include
int main (int argc, char *argv[])
{
if (argc < 0)
{
puts("Recursive call to main()");
}
else
{
while(argc > 0)
{
puts(argv[--argc]);
}
main(-1, NULL);
}
(void)argv;
return 0;
}

--
Pierre Maurette

Pierre Maurette
Le #1000083

[...]

{
while(argc > 0)
{
puts(argv[--argc]);
}
main(-1, NULL);
}
(void)argv;


Oooops! Dernière ligne inutile, après avoir ajouté l'affichage de la
ligne de commandes.

--
Pierre Maurette

candide
Le #1000081
On 10 août, 14:45, hibakusha
(Je suis sûr que la question à déja été posée, mais je n'arri ve pas a
mettre la main sur une réponse)


Elle l'a été a plusieurs reprises sur clc, cf. par exemple

http://groups.google.fr/group/comp.lang.c/msg/3e00366d8431f9bc?hl=fr&

où on retrouve l'argument de l'appel récursif main(-1, NULL).

Pascal Bourguignon
Le #999926
Pierre Maurette
2 - Il me semble que le "shall" s'adresse plutôt au shell ou au loader
qui va lancer main() dans un "hosted environment" avec les arguments
qui vont bien.


J'ai essayé de trouver une fonction exec qui prenne un argument argc,
mais non, elles prennent toutes seulement un argv terminé par 0, et
donc logiquement, argc en doit être déduit et ne peut donc pas être
négatif.


3 - Ce truc-là ne semble pas poser de problème, à part son inutilité
flagrante en l'état:

#include
int main (int argc, char *argv[])
{
if (argc < 0)
{
puts("Recursive call to main()");
}
else
{
while(argc > 0)
{
puts(argv[--argc]);
}
main(-1, NULL);
}
(void)argv;
return 0;
}


Oui. Une fois que main a pris la main, tout est possible.

--
__Pascal Bourguignon__ http://www.informatimago.com/

NOTE: The most fundamental particles in this product are held
together by a "gluing" force about which little is currently known
and whose adhesive power can therefore not be permanently
guaranteed.

espie
Le #999924
In article hibakusha

Bonjour à tous.

Pour le protoype suivant de main :

int main(int argc, char* argv[])

la norme indique pour argc :

"The value of argc shall be nonnegative."

L'utilisation de "shall" est perturbante, et je me demande ce qu'il
faut comprendre ici : est ce que cela veut bien dire que argc DOIT être
positif ? Et dans ce cas, pourquoi argc est il de type "int", c'est à
dire potentiellement négatif ?

Est ce moi qui comprends mal cette définition, ou bien y a t il la une
bizarerie, héritage quelconque d'un comportement etrange de certaines
version d'unix ou je ne sais quelle autre explication ?


Il y a deux choses: effectivement, c'est un heritage de temps obscurs,
en partie, ou les fonctions n'avaient pas de prototypes, et ou donc
int est le type `naturel' d'un parametre de fonction.

L'autre aspect, c'est que les valeurs non signes se pretent mal a
l'arithmetique: si ton argc entre dans une soustraction, et que le
resultat est negatif, tu es bien content de le savoir...
(je n'ai pas d'exemple non loufoque sous la main).

Vincent Lefevre
Le #995576
Dans l'article Pascal Bourguignon
Tout le monde est d'accord, ce serait mieux si c'était déclaré
unsigned int argc.


Non, je ne suis pas d'accord.

Mais le mélange de types entier N-bit non signés et de types entier
N-bit signés en complément à deux est toujours problématique, car les
intervales ne sont pas imbriqués, mais ont une intersection bizarre.


Voilà, les types non signés posent des problèmes et sont sources de
bugs (une valeur négative se retrouve facilement convertie en valeur
positive). De plus, ils ne permettent pas un contrôle d'overflow via
des traps (cf option -ftrapv de gcc).

Déclarer un type non signé juste parce qu'une valeur négative n'a pas
de sens, c'est idiot.

En C, on le voit par les différent warnings qu'un compilateur donne,
et sur les erreurs invisible comises quand on mélange les deux.


Le compilateur ne donne pas toujours de warning. Le pire, c'est quand
ça marche en 32 bits, mais plus du tout en 64 bits, car les promotions
se font différemment (e.g. une promotion en un type signé devient une
promotion en un type non signé, d'où bug sur les valeurs négatives).

--
Vincent Lefèvre 100% accessible validated (X)HTML - Blog: Work: CR INRIA - computer arithmetic / Arenaire project (LIP, ENS-Lyon)

Publicité
Poster une réponse
Anonyme