Répondre parce que toutes les réponses existantes disent que c'est un comportement indéfini, ce qui n'est pas vrai, donc je n'ai rien à voter.
En C89 (merci à pmg pour la référence à un projet de norme), 5.1.2.2.3 :
Un retour de l'appel initial à la fonction main équivaut à appeler la fonction exit avec la valeur renvoyée par la fonction main comme argument. Si le }qui termine la fonction principale est atteint, l'état de terminaison renvoyé à l'environnement hôte n'est pas spécifié.
Dans C99, citant n1256, 5.1.2.2.3 :
Si le type de retour de la fonction main est un type compatible int, un retour de l'appel initial à la fonction main équivaut à appeler la fonction exit avec la valeur retournée par la fonction main comme argument; atteindre le } qui termine la fonction principale renvoie une valeur de 0. Si le type de retour n'est pas compatible avec int, l'état de terminaison renvoyé à l'environnement hôte n'est pas spécifié.
Donc, ce n'est pas un "comportement indéfini" :il se comporte comme si le main
la fonction renvoie, mais en C89 la valeur renvoyée n'est pas spécifiée par la norme. Pour votre exemple de programme, sur votre implémentation, la valeur renvoyée semble toujours être 12, probablement pour la raison indiquée par Ben Voigt. Puisque vous êtes sous Linux, ce n'est probablement pas un gros changement de compiler votre code en C99 (ou de toute façon, de le compiler en utilisant le mode C99 presque conforme de gcc).
Pour toute fonction renvoyant une valeur autre que main
, c'est c'est comportement indéfini, à moins que l'appelant n'utilise pas la valeur de retour (n1256, 6.9.1/12) :
Si le } qui termine une fonction est atteint et que la valeur de l'appel de fonction est utilisée par l'appelant, le comportement est indéfini.
Je ne sais pas si l'appel initial à main
doivent être mentionnés comme exclus de cette règle générale. Ce n'est pas nécessaire :à partir du POV de la norme, cet appel n'a pas d'appelant, donc je pense que la valeur de l'appel de fonction n'est pas "utilisée par l'appelant", même si elle devient le statut de terminaison pour le programme.
Comme le dit swegi, c'est un comportement indéfini. Comme le disent Steve Jessop et al, c'est une valeur non spécifiée jusqu'à C89, et spécifiée dans C99 (le comportement observé est non conforme à C99)
Ce qui se passe réellement dans la plupart des environnements, c'est que la valeur de retour des derniers printf
est laissé dans le registre utilisé pour les valeurs de retour.
Donc ce sera 11 pour n ==0, 12 si n est un chiffre, 14 pour deux chiffres n, 16 pour trois chiffres n, etc.