Ils ont dit que cette expression est valide en C, et cela signifie appeler une fonction: peut-on expliquer clairement ce que cette expression signifie? P> J'ai essayé de Compilez ceci et a été surpris que cela n'a pas abouti à une erreur. P> p>
5 Réponses :
Vous créez un pointeur sur une fonction, puis appelez-le. Je ne l'appellerais pas une fonctionnalité cachée mais un comportement non défini.
En gros, vous le faites, mais avec l'adresse 0 à la place: p>
C'est un pointeur à une fonction à puis dans votre exemple que vous avez un casting: p> Alors vous la déréférez avec le premier astérisque (inutile, AFAIK), puis vous l'appelez. P> Vous appelez donc une fonction ne prenant aucun argument et que rien ne reviendra de vivre à l'adresse zéro. p> Ceci est (généralement) comportement non défini et va cracer instantanément sur de nombreuses plateformes. (Ce n'est pas un comportement indéfini si vous mettez une fonction à l'adresse zéro, au moins je ne penserais pas que c'était.) P> p> null code>.
void (*) () code> est la définition d'un pointeur à une fonction ne prenant aucune argument qui ne prend pas " t renvoie quoi que ce soit; Vous pouvez la nommer: p>
(my_func) 0 code> rendements un pointeur de fonction sur un
my_func code>, c'est-à-dire une fonction qui ne prend rien et ne renvoyant rien. p>
étape par étape: Le code a un comportement non défini, il s'agira probablement d'une sorte d'accès illégal / segfault. P> p>
@Steve Jessop: Merci pour la réponse détaillée
En fait, ce code aurait un comportement spécifique à la plate-forme que vous le compilez. Il peut être clairement défini pour certaines plates-formes et illégales sur les autres. J'ai récemment acheté un micro-contrôleur et quand il est activé, il exécute un code à partir de l'adresse 0 en mémoire. De sorte que le code saute au début du programme.
Droite, ce micro-contrôleur est l'un des cas qui signifie que probablement i> Crashes - la probabilité que Nguyendat utilise une plate-forme où elle ne sera pas faible ;-) Quand je dis "comportement indéfini" Bien sûr, je veux dire, comme toujours, non défini par la norme C. Des implémentations particulières peuvent garantir ce qu'ils feront en particulier des cas de comportement indéfini.
Dans une seule plate-forme d'adresse d'adresses (ou dans un environnement non hébergé, c'est-à-dire que vous êtes le noyau), cela est possible et pourrait être un moyen de réinitialiser une réinitialisation complète du système. (Lorsque le vecteur de réinitialisation est à l'adresse 0, qui peut contenir du code bootstrap (en ROM?) sans aucun symbole exporté pour le lien, vous pourrez appeler la fonction Bootstrap à l'aide du nom de la fonction)
@alvin: Bien qu'il soit toujours plus propre d'utiliser un script de liaison pour définir un symbole et l'appeler comme une fonction.
@Zan, ah oui. Ou peut-être juste une macro :) #define reset () do {( (void ( i>) ()) 0) ()}}} tandis que (0)
cassez-le par parenthèse. P>
Le dernier La ligne Le dernier petit bit, le Si fondamentalement, vous appelez quel que soit le diable réside à l'adresse 0 sans paramètres. Pas généralement très sûr. :) p> () code> signifie une fonction sans paramètres. P>
(void (*) () ()) code> signifie une fonction qui renvoie nul. p>
(* code> au début et au
0) code> indique au compilateur que l'adresse de la fonction d'appel à des mensonges du pointeur 0. p>
Dans un environnement intégré, pourrait être un moyen d'appeler la routine de réinitialisation du système. p>
Bizarre d'appeler cela une fonctionnalité cachée.
"Ce n'est pas un comportement indéfini ... c'est une fonctionnalité!". Non, c'est un comportement indéfini.