9
votes

Détecter l'utilisation de la macro? (errno)

Ceci est très spécifique et un peu difficile à expliquer, et très probablement impossible, mais voilà.

Je veux mettre en œuvre . (Mon projet de passe-temps met en œuvre une norme C Bibliothèque.)

La voie naïve à faire est: xxx < p> Cela fonctionne. Mais il a un inconvénient: si une fonction de bibliothèque de mathématiques est appelée, elle toujours doit interroger l'état FPU après exécution pour définir errno selon le cas. Cela stipule le FPU dans des applications math-lourdes.

La norme C endossise une évaluation paresseuse de errno en faisant une macro à la place: xxx

de cette façon, errno est uniquement "défini" lorsque sa valeur est réellement demandée: xxx

donné Quelques logiques dans le reste de la bibliothèque, le statut FPU ne doit être interrogé que si la dernière fonction de la bibliothèque appelée était en réalité un en utilisant le FPU, et la valeur de errno est réellement demandé .

jusqu'à présent, tout va bien. Mais c'est l'inverse qui me donne des maux de tête: xxx

La valeur de errno n'est pas demandée du tout. mais __ errno () ne sait pas cela et interrogera le statut FPU si la dernière fonction de la bibliothèque appelée utilisait le FPU.

ne vois pas un moyen d'éviter cela (c'est-à-dire avoir le errno macro ou le __ errno () fonctionne en quelque sorte fonctionner différemment selon qu'ils sont utilisés à gauche ou à la droit de l'opérateur d'affectation), et je suis presque content d'accepter cela.

Mais peut-être que l'une d'entre vous a donc une idée brillante?


0 commentaires

3 Réponses :


4
votes

Aucune idée brillante ici, mais Afaik errno est autorisé à être mis en œuvre via des appels de fonction pour effectuer des implémentations de fil de sécurité de la bibliothèque standard possible. Je ne pense pas que l'interrogation du FPU Lazily est une bonne idée: Comment éviterez-vous une incohérence dans des situations comme celle-ci:

  • SET ERRNO
  • POINT POINTS FLOTANTES QUI SET ERREUR DES DRAPHAGES
  • Obtenez errno
  • Obtenez des drapeaux

    doit appeler à __ errno () effacer les drapeaux ou non?

    Selon la norme, si errno doit être défini par les fonctions mathématiques est déterminé par la valeur de math_errhandling (spécifiquement, math_errhandling & math_errno < / code>).

    Ce que je ferais, c'est faire le signalement des erreurs facultatif via des directives de préprocesseur et permettre au programmeur de définir la valeur de math_errhandling au moment de la compilation. Cela signifierait que les fonctions mathématiques ne peuvent pas être compilées de manière statique mais doivent résider dans un en-tête, ce qui pourrait être une bonne idée de toute façon pour permettre aux compilateurs sans optimisations de temps de liaison à ces fonctions.


0 commentaires

2
votes

Ce que vous avez ici est une analyse assez bonne de la raison pour laquelle l'ensemble du mécanisme errno code> est si insatisfaisant. Vous pouvez trouver une analyse similaire dans la "bibliothèque standard C" de Kernighan.

La forme fonctionnelle de errno code> est également nécessaire pour les implémentations de fil-sécurité, où différents threads ont des valeurs d'erreur distinctes accessibles via un Spécifique du fil errno code>. p>

Votre macro devrait probablement avoir des parenthèses autour de celui-ci pour la sécurité: P>

#define errno (*__errno())


0 commentaires

1
votes

Plus d'un commentaire qu'une réponse, mais sans formatage de code, il ne serait pas compréhensible.

Si vous vérifiez la paresseuse des drapeaux FPU, comment auriez-vous le comportement correct (les fonctions mathématiques sont spéciales en ce sens qu'ils sont garantis ne pas modifier errno quand il n'y a pas de problème)? P>

errno = 0;
x = acos(y);
z = <exp>;
if (errno != 0) {
   /* can't come here even if y is a valid argument but <exp> modified the flags if it didn't call any functions */
}


0 commentaires