visual Que signifie "empoisonner une fonction" en C++?




visual c++ constexpr (2)

À la toute fin de son discours "Présentation de constexpr " à la CppCon , Scott Schurr demande "Y a-t-il un moyen d'empoisonner une fonction"? Il explique ensuite que cela peut être fait (bien que de manière non standard) en:

  1. Mettre une constexpr dans une fonction constexpr
  2. Déclaration d'un caractère extern const char* non résolu extern const char*
  3. Référencer l' extern non résolu dans le throw

Je sens que je suis un peu hors de ma profondeur ici, mais je suis curieux:

  • Que signifie "empoisonner une fonction"?
  • Quelle est la signification / utilité de la technique qu'il décrit?

En général, il s'agit de rendre une fonction inutilisable. Par exemple, si vous souhaitez interdire l'utilisation de l'allocation dynamique dans un programme, vous pouvez "empoisonner" la fonction malloc afin qu'elle ne puisse pas être utilisée.

Dans la vidéo, il l'utilise d'une manière plus spécifique, ce qui est clair si vous lisez la diapositive affichée lorsqu'il parle d'empoisonner la fonction, qui indique "Un moyen de forcer uniquement le temps de compilation?"

Il parle donc d ’" empoisonnement "de la fonction pour la rendre non appelable au moment de l’exécution, elle ne peut donc être appelée que dans des expressions constantes. La technique consiste à avoir une branche dans la fonction qui n’est jamais utilisée lorsqu’elle est appelée dans un contexte de compilation, et à faire en sorte que cette branche contienne quelque chose qui provoquera une erreur.

Une expression de projection est autorisée dans une fonction constexpr, à condition qu'elle ne soit jamais atteinte lors des appels de la fonction à la compilation (car vous ne pouvez pas lever une exception lors de la compilation, il s'agit d'une opération intrinsèquement dynamique, comme l'allocation de mémoire). Ainsi, une expression qui fait référence à un symbole non défini ne sera pas utilisée lors des appels à la compilation (car la compilation échouera) et ne peut pas être utilisée à l'exécution, car le symbole non défini provoque une erreur de l'éditeur de liens.

Étant donné que le symbole non défini n'est pas "utilisé par odr" dans les invocations de la fonction à la compilation, en pratique, le compilateur ne créera pas de référence au symbole. Il est donc normal qu'il ne soit pas défini.

Est-ce utile? Il montre comment faire, sans nécessairement dire que ce soit une bonne idée ou une grande utilité. Si vous avez besoin de le faire pour une raison quelconque, sa technique pourrait résoudre votre problème. Si vous n'en avez pas besoin, vous n'avez pas besoin de vous en inquiéter.

Une raison pour laquelle cela pourrait être utile est lorsque la version au moment de la compilation d’une opération n’est pas aussi efficace qu’elle pourrait l’être. Il existe des restrictions sur le type d'expressions autorisées dans une fonction constexpr (en particulier dans C ++ 11, certaines restrictions ont été supprimées dans C ++ 14). Donc, vous pouvez avoir deux versions d’une fonction pour effectuer un calcul, une optimale, mais utilisant des expressions qui ne sont pas autorisées dans une fonction constexpr, et une qui est une fonction constexpr valide, mais qui fonctionnerait mal si elle était appelée à l’exécution. temps. Vous pouvez empoisonner la solution sous-optimale pour vous assurer qu'elle n'est jamais utilisée pour les appels d'exécution, en vous assurant que la version la plus efficace (non-constexpr) est utilisée pour les appels d'exécution.

Remarque: Les performances d'une fonction constexpr utilisée au moment de la compilation ne sont pas vraiment importantes, car de toute façon, elles ne génèrent pas de temps système. Cela pourrait ralentir votre compilation en faisant en sorte que le compilateur fasse un travail supplémentaire, mais cela n'entraînera aucun coût en performances d'exécution.


"Empoisonnement" un identifiant signifie que toute référence à l'identifiant après "l'empoisonnement" est une erreur matérielle du compilateur. Cette technique peut être utilisée, par exemple, pour une forte dépréciation (la fonction est dépréciée, ne l'utilisez jamais!).

Traditionnellement, il existait un pragma dans #pragma GCC poison : #pragma GCC poison .





constexpr