11
votes

C - Qu'est-ce que cette ligne signifie?

J'essaie de comprendre quelle est la ligne suivante du code C pire jamais vu (de UBOOT projet) MOOD:

rc = ((ulong (*)(bd_t *, int, char *[]))addr) (bd, --argc, &argv[1]);


12 commentaires

Pouvez-vous nous dire le type déclaré des différentes variables présentes dans cette ligne?


Peut-il être plus lisible? Sûrement pas! Obfusque ça!


@David: Je suis désolé, mais je n'ai aucune idée. Je viens d'ouvrir ce projet et j'essaie de comprendre ce qui est quoi.


C'est mauvais programmeur pour "courir hurlant".


Je suis impressionné. C'est un enfer de C-Fu.


@ADAM: Oui, mais vous devez admettre qu'il est étonnant de beaux dans son horreur intrinsèque.


Stefano, je vais admettre que cela a une certaine qualité de Lovecrafe.


Pourquoi ne demandez-vous pas de demander CDECL ?


MMMM coulée pour fonctionner dessert du pointeur avec --Argc cerise sur le dessus: o) c'est réellement lisible, juste une analyse mentale peut prendre un certain temps. L'adresse du projet correct BTW est la suivante: Denx.de/wiki/u-boot/webhomeleight/a >


@Mar: merci pour l'adresse mise à jour


Vous devriez lire le commentaire qui est juste au-dessus de cette ligne. Ça dit ... Attends! Il n'y a pas de commentaire! ÉCHOUER!


maintenant je me souviens pourquoi je déteste 'c'


6 Réponses :


12
votes

Il diffuse addr à un pointeur de fonction qui accepte (bd_t *, int, char * []) ​​ comme arguments et retourne un long , puis appelez-le avec les arguments (bd, -argc et argv [1]) .


9 commentaires

Droit. Et pour répondre à la deuxième question, non, il ne peut pas être rendu plus lisible.


@Jason: Bien sûr, cela peut (et devrait) voir la réponse de Lewind.


Le sillage de Finnegan est également parfaitement lisible, mais l'extraction de la signification est sensiblement difficile.


@ T.J. Crowder: Cela déplace simplement la défense perçue ailleurs. (Pour être clair, je ne suis pas d'accord que l'une ou l'autre version est illisible. Juste que si quelqu'un devait trouver la partie originale illisible et déchargée de la non-lecture ailleurs n'a pas réduit la non-lecture.)


@Stephen: Beaucoup de programmeurs C, en particulier les plus récents, n'ont pas à gérer les pointeurs de fonction souvent. De plus, la pratique de la programmation est bien meilleure pour déclarer le type de pointeur (si vous allez avoir à en utiliser un) dans la même en-tête où vous déclarez la fonction, de sorte que si vous devez modifier la fonction, vous ne casserez pas tous les Cast individuel codé à la main. Entretien 101, à mon avis.


Je ne vois pas d'utiliser un Typedef comme une amélioration de la lisibilité, mais si le type de pointeur de fonction est utilisé dans plusieurs endroits, il est logique d'utiliser un pour enlever la duplication. Toutefois, si le type de pointeur de fonction est un seul éteint, je ne vois pas de problème à l'utiliser en ligne. Mes deux centimes.


@Jason: Je ne suis pas d'accord, pour les raisons de mon commentaire à Stephen. Mais tout est bon, les gens intelligents peuvent être en désaccord les uns avec les autres. :-)


@ T.J. Crowder: Je suis tout à fait d'accord avec vos commentaires de maintenance; C'est une très bonne raison de fournir un tel Typedef . Je conviendrai que nous pouvons accepter d'agréablement être en désaccord sur le fait que cela améliore ou non la lisibilité à une personne qui ne trouve pas la version originale lisible. :-)


Déchargement partie difficile à Typedef aide aux scénarios où vous lisez le code, mais ne souhaitez pas inspecter en détail ce bit particulier. Avec Typedef, il ressemble à un appel de fonction ordinaire et vous pouvez "analyser" plus rapidement. En revanche, cela peut être désétachée lorsque vous recherchez des erreurs étranges si - par exemple, votre pointeur de fonction n'est pas défini correctement. Une bonne nommée est essentielle lorsque Typef (comme FP_ ou quelque chose) afin que vous puissiez détecter les pointeurs de fonction si vous en avez besoin.



2
votes

ulong (*) (bd_t *, int, char * []) ​​ est le type d'une fonction qui prend un pointeur sur un bd_t , un INT et un pointeur sur un tableau Char et renvoie un ulong .

Le code est casting addr à une telle fonction, puis appelez-le avec bd , - argc et & argv [1] comme paramètres et attribuant le résultat à rc .


0 commentaires

34
votes

Oui, c'est un appel de la fonction.

Il jette la valeur dans addr à un pointeur de fonction qui accepte (bd_t *, int, char * []) ​​ Comme arguments et renvoie un ulong et appelle la fonction. Il pourrait être sucré dans: xxx

ceci pourrait être surchargé, pour introduire un Typedef si cela ne se produit qu'une fois, mais je pense que cela aide beaucoup Pour pouvoir regarder le type du pointeur de fonction séparément.


2 commentaires

Puisque le typdef fait la chose lisible, il n'est pas trop excité.


Il n'est pas trop excédé de la même manière que les antibiotiques ne sont pas une réaction excessive à l'infection.



1
votes

Vous avez la touche "addr" à un pointeur à une fonction renvoyant une ulong qui prend un BD_T *, un INT et un char * [] comme paramètres, puis appelant la fonction avec les paramètres BD, --Argc, & argv [1].


0 commentaires

2
votes
Adresse doit être l'emplacement en mémoire à une fonction qui ressemble à xxx pré>

et il est appelé avec les paramètres tels que P>

rc = funcname(bd, --argc, &argv[1]);

0 commentaires