96 votes

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

À la fin de Scott Schurr de parler "d'Introduire constexpr" à CppCon, il demande "Est-il un moyen de poison une fonction"? Il explique alors que cela peut être fait (quoique d'une façon non standard) par:

  1. Mettre un throw en constexpr fonction
  2. Le fait de déclarer un non résolus extern const char*
  3. Référencement du suspens extern dans la throw

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

  • Que signifie "poison " fonction"?
  • Quelle est la signification de l'utilité de la technique qu'il décrit?

106voto

Jonathan Wakely Points 45593

En général, il se réfère à une prise de fonction inutilisable, par exemple, si vous souhaitez interdire l'utilisation de l'allocation dynamique dans un programme de "poison" l' malloc fonction de sorte qu'il ne peut pas être utilisé.

Dans la vidéo, il l'utilise de façon plus spécifique, ce qui est clair, si vous lisez la diapositive qui est affiché quand il parle de l'empoisonnement de la fonction, qui dit: "Un moyen de forcer la compilation?"

Donc, il parle de "l'empoisonnement" de la fonction pour en faire uncallable au moment de l'exécution, de sorte que c'est seulement appelable dans des expressions constantes. La technique est d'avoir une direction dans la fonction qui n'est jamais prise lorsqu'il est appelé au moment de la compilation contexte, et faire que la direction de contenir quelque chose qui va provoquer une erreur.

Un throw expression est autorisée dans un constexpr fonction, tant qu'il n'est jamais atteint au cours de la compilation des invocations de la fonction (car vous ne pouvez pas lancer une exception au moment de la compilation, c'est par nature un fonctionnement dynamique, comme l'allocation de mémoire). Ainsi, un jet d'expression qui fait référence à un symbole non défini ne sera pas utilisé lors de la compilation des invocations (parce que de ne pas compiler) et ne peut être utilisé au moment de l'exécution, parce que le symbole non défini provoque une erreur de l'éditeur de liens.

Parce que le symbole non défini n'est pas "odr" dans la compilation des invocations de la fonction, dans la pratique, le compilateur ne va pas créer une référence au symbole, de sorte qu'il est d'accord que c'est pas défini.

Est-il utile? Il démontrant comment le faire, pas nécessairement dire que c'est une bonne idée ou très utile. Si vous avez besoin de le faire pour une raison quelconque, alors sa technique peut résoudre votre problème. Si vous n'avez pas besoin, vous n'avez pas besoin de s'inquiéter à ce sujet.

Une raison pour laquelle il pourrait être utile, c'est quand le moment de la compilation de la version d'une opération n'est pas aussi efficace qu'elle pourrait l'être. Il y a des restrictions sur le type des expressions dans un constexpr fonction (surtout en C++11, certaines restrictions ont été supprimées en C++14). De sorte que vous pourriez avoir deux versions d'une fonction pour effectuer un calcul, celui qui est optimale, mais utilise des expressions qui ne sont pas permis dans un constexpr fonction, et qui est valide constexpr fonction, mais serait effectuer très mal si elle est appelée au moment de l'exécution. Vous pourriez poison de la sous-optimale pour s'assurer qu'il n'est jamais utilisé pour l'exécution des appels, d'assurer la plus efficace (non-constexpr) qui est utilisé pour l'exécution des appels.

N. B. La performance d'un constexpr fonction utilisée au moment de la compilation n'est pas vraiment important, parce qu'il n'a pas d'exécuter à temps les frais généraux de toute façon. Il peut ralentir votre compilation en faisant le compilateur de faire du travail supplémentaire, mais il n'aura pas toutes les performances d'exécution de coût.

17voto

SergeyA Points 2159

"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 GCC: #pragma GCC poison .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X