La signature non standard de main () comstack avec succès

Dans ce code:

int main(int a, int b) { printf(" main(int, int) works \n\n"); return 0; } 

la signature de main est main(int, int) et se comstack avec succès . Pourquoi?

Parce que la norme C n’interdit pas les signatures non standard pour la signature main (voir par exemple la section 5.1.2 de la norme C99).

Cependant, vous constaterez que si vous comstackz sous GCC avec le drapeau -Wall , il se plaindra:

 test.c:4: warning: second argument of 'main' should be 'char **' 

Cela suppose que vous souhaitiez interagir avec un environnement standard (c’est-à-dire traiter les parameters de ligne de commande et renvoyer un statut de sortie), auquel cas vous devez utiliser int main(int, char **) ou int main(void) . Si vous utilisez autre chose, le contenu des arguments sera indéfini.


1. J’aimerais vraiment que ideone.com vous permette de spécifier les drapeaux du compilateur!

La norme C interdit spécifiquement à la mise en oeuvre de fournir un prototype pour main (C99, §5.1.2.2.1 / 1: “La fonction appelée au démarrage du programme est appelée main . La mise en oeuvre ne déclare aucun prototype pour cette fonction.”), Et une Une incompatibilité du prototype est ce qui empêcherait (normalement) le code de comstackr.

Sans prototype, vous revenez à la programmation comme au bon vieux temps, lorsque vous deviez vous assurer que les arguments que vous avez passés à une fonction correspondaient à ce à quoi elle s’attendait. Heureusement, dans le cas de main , la signature est si bien connue que c’est rarement un problème.

Edit: notez que si vous voulez assez, il est même possible d’utiliser la version avec deux parameters int (bien que la technique soit interdite en C ++). main peut s’appeler de manière récursive, et dans un tel cas peut / peut transmettre deux parameters int :

 int main(int a, int b) { if (a == 2) main(2, 10); printf("%d, %d", a, b); return 0; } 

C’est plutôt inutile en l’état, mais donne l’idée générale – vous êtes censé exécuter le programme sans argument en ligne de commande, auquel cas a (qui recevra ce que vous appelez normalement argc ) sera normalement 1 (c.-à-d., le seul argument qu’il essaie de transmettre est le nom du programme dans argv [0]). Dans ce cas, il s’appelle avec d’autres valeurs. Lorsque cela se produit, ces valeurs sont imprimées.

Pour être juste, je devrais append que c’est assez proche de purement théorique, et certainement pas recommandé. Cela fonctionnera avec la plupart des implémentations classiques, mais le standard ne le garantit pas. C’est une façon idiote et détournée d’accomplir ce qu’elle fait – mais au moins avec la plupart des compilateurs classiques, c’est (à peine) possible de toute façon.

Il n’y a pas de fichier d’en-tête qui spécifie la signature de main, donc aucune erreur ne sera rapscope. Le compilateur vérifie généralement la valeur de retour uniquement, dans le cas de main (les avertissements de la signature de main dépendent du compilateur).

 int main(int a, int b) 

cela n’a pas de sens car les arguments passés à la fonction principale sont toujours

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

main est une fonction inhabituelle. Il est appelé par le système d’exploitation. C ++ pouvant s’exécuter sur de nombreux systèmes, les normes C ++ ne peuvent pas dicter aux auteurs de système d’exploitation les données transmises aux programmes s’exécutant sur ce système d’exploitation. les fonctions principales et le compilateur l’accepteront.