Selon Cette réponse à l'aide de la fonction principale () est illégale em> (§3.6. 1.3) et une fonction est utilisée em> si son nom apparaît dans une expression potentiellement évaluée (§3.2). Supposons que j'ai ce code: p> printf( "%p", &main );
3 Réponses :
Etant donné que Main code> n'est pas "utilisé" (vous n'agitez pas) alors il devrait être légal en fonction du lien que vous avez fourni. P>
Prendre l'adresse d'une fonction l'utilise.
Oui. Comme vous citez, la norme indique que vous ne pouvez pas utiliser
note aussi que l'adresse d'une fonction ne pas em> correspondre principal code>. p>
"% p" code>.
L'argument correspondant doit em> avoir type
vide * code>; tout autre
Type (sauf peut-être peut-être
char * code>) est illégal et donne des résultats non définis
comportement. p>
Ainsi, aurai-je besoin d'une distribution pour l'adresse de fonction pour la transmettre à la place de % p code>?
@shachartooth sauf qu'il n'y a pas de conversion de pointeur sur fonctionner à vide * code>. (Je pense que C ++ 11 en fait une fonctionnalité facultative, mais dans des versions antérieures, elle nécessitait un diagnostic.)
Il n'est pas habituel d'utiliser le pointeur vers Quoi qu'il en soit, il est autorisé depuis, comme chaque fonction (et n'importe quel symbole, par exemple la variable) a sa propre adresse. Et l'adresse de la principale () peut être nécessaire - en particulier lorsque vous écrivez le code des systèmes embarqués et que vous jouez avec le chargement dynamique du code ou de l'inspection de temps d'exécution. Ou il y a un chargeur de démarrage et un micrologiciel exécutant réel. P>
Souvent Voir MicroC-OS / II ou VXWorks - utilisez les deux principal () code> ou l'adresse de
principal () code> mais .. p>
principal () code> est un point d'entrée sur le code chargé de manière dynamique (par exemple de Flash à la RAM) et est ainsi référencé (appelé directement ou attribué au pointeur correspondant) dans le chargeur de démarrage. p>
principal () code> de cette manière p>
Malheureusement ... cela est complètement en dehors de la norme. La mise en œuvre est autorisée à tout le code de la magie noire, de la plate-forme, du code spécifique au compilateur qu'il peut rassembler; Mais cela ne dit rien sur la portabilité i> du programme à une autre plate-forme / compilateur.
Je suppose que l'économiseur de vie dans des systèmes embarqués est que le principal () peut être remplacé par quelque chose de complètement personnalisé. Donc, comme la norme C ++ est retardée, toutes les implémentations C ++ incorporées doivent renommer leur principal à autre chose. Je propose que tous les systèmes embarqués utilisent autre_wg21_fiasco () code> au lieu de
principal () code>, pour résoudre ce problème. Ou ... ils pourraient simplement conserver la programmation en C, où la norme est moins attachée.
§3.2 Définit " odr-utilisé-utilisé i>", pas "utilisé". Je pense que la signification de "utilisé" ici est beaucoup plus générale - vous ne pouvez pas utiliser
principal code> de quelque manière que ce soit.
Bonne question. Par curiosité - pourquoi auriez-vous besoin de cela? Ou poser votre question est basé sur la même chose, je demande le mien :)
@sftrabbit c ++ 03 dit clairement: "Une fonction objet ou non surchargé est utilisée si son nom apparaît dans une expression potentiellement évaluée." C ++ 11 ne dit pas ce que cela signifie par "utilisé"; Je suppose que "ODR-utilisé" a été introduit pour résoudre un autre problème et personne n'a eu le tour de la rétraction de la restriction sur
principal code>.
@Jameskanze ah, je regardais C ++ 11.
Voir aussi Cette question concernant l'impression d'un pointeur de fonction.
@sftrabbit Les mots limitant l'utilisation de
principal code> sont les mêmes dans les deux versions. Je ne trouve pas de définition réelle sur ce que "utilisé" signifie en C ++ 11, cependant; À moins que quelqu'un puisse me montrer autre chose, je suppose que l'intention est la même que dans C ++ 03.
@Kirilkirov: Je ne sais pas pourquoi j'avais besoin de cela. Je pense que ce serait une bonne question distincte.
Cela semble être une règle terriblement muette. Cela interdire efficacement C ++ de toutes sortes de chargeurs de démarrage et de code d'initialisation à fonctionner avant que le principal () soit appelé. Dans le même temps, la norme C ++ dicte que ce code doit exister, pour gérer l'initialisation statique et exécuter des constructeurs d'objets de portée de fichier. Je suppose que vous êtes obligé d'écrire ce code en C ou en assembleur.