Dans de nombreux langages tels que C, C ++ et Java, la main
méthode / fonction a un type de retour de void
ou int
, mais pas double
ou String
. Quelles pourraient être les raisons derrière cela?
Je connais un peu que nous ne pouvons pas le faire parce que l' main
on appelle par la bibliothèque d'exécution et il attend à une syntaxe comme int main()
ou int main(int,char**)
si nous devons nous en tenir à cela.
Ma question est donc la suivante: pourquoi main
une signature de type at-elle été utilisée et non une signature différente?
Réponses:
La valeur de retour de
main
doit être transmise au système d'exploitation ( tout système d'exploitation) d'une manière unique et cohérente. Les informations que le système d'exploitation doit connaître sont "le programme s'est-il arrêté correctement ou y a-t-il une erreur?"S'il s'agit d'une chaîne, la réponse devient difficile dans différentes langues. Les éléments internes d'une chaîne Pascal (le premier octet est de longueur) et d'une chaîne FORTRAN (fixée, complétée à une valeur) et d'une chaîne C (terminée par un caractère nul) sont tous différents. Cela rendrait difficile le retour d'une valeur cohérente au système d'exploitation. En supposant que cela soit résolu, que feriez-vous pour répondre à la question du système sur le système d'exploitation? Les comparaisons de chaînes sont entachées d'erreurs ("succès" ou "succès"), et si l'erreur peut être plus utile pour un humain, elle est plus difficile à gérer pour le système d'exploitation ou un autre programme (shell). Il y avait aussi des différences significatives, même dans les chaînes elles-mêmes - EBCDIC (avec toutes ses pages de code) par rapport à ASCII.
Les flottants et les doubles ne fournissent aucune valeur supplémentaire sur l'entier pour la communication de données en retour au système d'exploitation (et au shell). Pour la plupart, aucune de ces parties de l'ordinateur ne traite de nombres à virgule flottante. Les doubles ne sont pas non plus énumérables, ce qui rend les comparaisons difficiles. N'étant pas énumérables, ils rendent compte de l'erreur (en supposant que vous ayez choisi une valeur particulière pour réussir). Encore une fois, les points flottants ne sont pas cohérents - un float sur une machine 8 bits était différent de celui des machines 16 bits et 32 bits (et ce ne sont que des machines «normales» - même au sein d'IBM, la virgule flottante n'était pas normalisée. entre les machines du même fabricant jusqu’aux années 1980). Et puis vous avez des ordinateurs décimaux contre des ordinateurs binaires. Les valeurs en virgule flottante ne sont pas cohérentes et ne fournissent pas de données significatives.
Cela nous laisse vraiment avec les octets et les nombres entiers comme options. La convention qui a été établie était «0» était un succès, et toute autre chose était une erreur. Un entier donne plus de place qu'un octet pour signaler l'erreur. Il peut être énuméré (retour de 1 signifie XYZ, retour de 2 signifie ABC, retour de 3, DEF, etc.) ou utilisé en tant qu'indicateur (
0x0001
signifie que cet échec a0x0002
signifié que0x0003
cela a échoué. Limiter cela à un seul octet pourrait facilement manquer de drapeaux (seulement 8), la décision était donc probablement d'utiliser un entier.la source
main()
est appelé de différentes manières sur différents systèmes d'exploitation. En C, comment la méthode main () est-elle initialement appelée? va dans cela.main
- contrairement aux autres fonctions de tout programme - ne fait pas partie d'un protocole défini par le programmeur, mais du protocole utilisé pour assurer l'interface avec l'hôte (OS). Vous ne pouvez pas le choisir parce que vous ne l'avez jamais choisi. À un niveau plus pragmatique, UNIX s'attend à ce qu'un int soit renvoyé par un processus. Le protocole C-to-UNIX fait exactement cela. Un argument analogue peut être utilisé pour le passage d’arguments: si C avait été inventé pour un système d’exploitation / hôte qui ne passait que des nombres comme arguments (par exemple, aucune ligne de commande), les arguments seraient des entiers au lieu de chaînes.Eh bien, ça pourrait .
Par exemple, dans le dialecte de C utilisé dans le système d’exploitation Plan 9 , il
main
est normalement déclaré en tant quevoid
fonction, mais l’état de sortie est renvoyé à l’environnement appelant en transmettant un pointeur de chaîne à laexits()
fonction. La chaîne vide indique un succès et toute chaîne non vide indique un type d'échec. Cela aurait pu être implémenté enmain
renvoyant unchar*
résultat.Et il serait certainement possible de mettre en place un système avec un statut
float
ou undouble
statut de sortie.Alors pourquoi
int
? C'est juste une question de convention - et il est extrêmement précieux de faire en sorte que les systèmes d'exploitation et les programmes qui y sont exécutés obéissent à une convention commune.La convention Unix consiste à utiliser un code d’état entier, 0 indiquant la réussite et non nul indiquant l’échec (car il n’ya généralement qu’une seule façon de réussir, mais plusieurs façons d’échouer). Je ne sais pas si cette convention a son origine avec Unix; Je soupçonne que cela provient de systèmes d'exploitation antérieurs.
La convention en virgule flottante serait une convention plus difficile, car (a) la prise en charge de la virgule flottante n’est pas universelle, (b) il est plus difficile de définir un mappage entre les valeurs en virgule flottante et les conditions d’erreur, (c) différents systèmes utilisent différentes méthodes de calcul. (d) imaginez simplement le plaisir de détecter une erreur d’arrondi dans le statut de sortie de votre programme. Les entiers, par contre, se prêtent très bien à l'énumération des codes d'erreur.
Plan 9, comme je l'ai mentionné, utilise des chaînes, mais cela impose une certaine complexité pour la gestion de la mémoire, l'encodage des caractères, etc. Il s'agissait, pour autant que je sache, d'une nouvelle idée lorsque Plan 9 l'a mise en œuvre, et cela ne remplace pas l'existant. convention répandue.
(Incidemment, le C ++
main
ne peut que revenirint
, et le Cvoid main
n'est autorisé que si le compilateur le supporte spécifiquement. De nombreux compilateurs ne se plaignent pas très fort si vous écrivezvoid main
, mais ce n'est qu'une légère exagération de dire que c'est faux .)la source
La valeur renvoyée par la méthode principale est un "code de sortie". Il est utilisé par l’appelant appelant (normalement bash) pour vérifier si le programme s’est terminé comme prévu. Renvoyer un entier est le moyen le plus simple de le faire au niveau du système d'exploitation. Double n'a aucun sens pour le code d'erreur et une chaîne est difficile à maintenir au niveau du système d'exploitation (il n'y a pas de GC).
la source
main doit renvoyer l’état du programme qui est exécuté. Que celui-ci soit exécuté avec succès (0, EXIT_SUCCESS) ou non (1 signifie EXIT_FAILURE). Un nombre autre que zéro transmet le même sens, mais zéro n’indique aucune erreur ni exécution réussie.
la source