40 votes

Pourquoi une langue n'utiliserait-elle PAS l'évaluation de court-circuit?

Pourquoi une langue n'utiliserait -elle PAS l' évaluation de court-circuit ? Y a-t-il des avantages à ne pas l'utiliser?

Je vois que cela pourrait entraîner des problèmes de performances ... est-ce vrai? Pourquoi?


Question connexe: Avantages de l'utilisation de l'évaluation des courts-circuits

41voto

RBarryYoung Points 23349

Raisons de ne PAS utiliser de court-circuit de l'évaluation:

  1. Parce qu'il va se comporter différemment et produisent des résultats différents si vos fonctions, à la propriété Obtient ou opérateur méthodes ont des effets de bord. Et cela peut entrer en conflit avec: A) les Normes Linguistiques, B) les versions précédentes de votre langue, ou C) les hypothèses par défaut de vos langues les utilisateurs typiques. C'est pour ces raisons que VB est pour ne pas court-circuit.

  2. Parce que vous pouvez vouloir que le compilateur pour avoir la liberté de vous réorganiser et tailler les expressions, les opérateurs et les sous-expressions comme il l'entend, plutôt que dans l'ordre que l'utilisateur a tapé dans. Ce sont les raisons pour SQL pour ne pas court-circuit (ou au moins pas de la manière que la plupart des développeurs venant de SQL pense qu'il serait). Ainsi, SQL (et quelques autres langues) peuvent court-circuit, mais seulement si elle en décide, et pas nécessairement dans l'ordre que vous avez implicitement spécifié.

Je suppose ici que vous posez sur "automatique, commande implicite court-circuit", qui est ce que la plupart des développeurs s'attendent à partir de C,C++,C#,Java, etc. Les deux VB et SQL ont les moyens explicitement les force de l'ordre spécifique de court-circuit. Pourtant, d'habitude, quand les gens posent cette question, c'est un DWIM* question, ils veulent dire "pourquoi ne pas Faire Ce que je Veux?", comme dans, automatiquement court-circuit dans l'ordre que je l'ai écrit.

*- DWIM = "Faire Ce que je voulais"

7voto

Benoit Points 39210

Un avantage auquel je peux penser est que certaines opérations peuvent avoir des effets secondaires que vous pourriez vous attendre.

Exemple:

 if (true || someBooleanFunctionWithSideEffect()) {
    ...
}
 

Mais c'est généralement mal vu.

5voto

T.E.D. Points 26829

Ada ne le fait pas par défaut. Afin de forcer les court-circuit d'évaluation, vous devez utiliser and then ou or else au lieu de and ou or.

Le problème est qu'il y a certaines circonstances où ça ralentit les choses. Si la deuxième condition est rapide à calculer et à la première condition, il est presque toujours vrai pour "et" faux "ou", puis la vérification supplémentaire-direction de l'instruction est une sorte de déchets. Cependant, je comprends qu'avec les processeurs modernes de la direction générale de prédicteurs, ce n'est pas tellement le cas. Un autre problème est que le compilateur peut arriver à savoir que la deuxième moitié est moins cher ou susceptibles d'échouer, et peut souhaitez réorganiser le chèque en conséquence (ce qu'il ne pouvait pas le faire si un court-circuit comportement est défini).

J'ai entendu les objections qu'il peut entraîner un comportement inattendu du code dans le cas où le deuxième test a des effets secondaires. À mon humble avis il n'est "inattendu" si vous ne savez pas très bien votre langue, mais certains soutiennent cette.

Dans le cas où vous êtes intéressé par ce langage même les concepteurs ont à dire à propos de cette question, voici un extrait de l' Ada 83 (langue d'origine) Justification:

Les opérandes d'une expression booléenne comme A et B peuvent être évaluées en toute commande. En fonction de la complexité le terme B, il peut être plus efficace (sur certains mais pas tous les machines) pour évaluer B uniquement lorsque le le terme A a la valeur TRUE. Cette cependant, une optimisation de la décision prises par le compilateur, et il serait incorrect de supposer que ce l'optimisation est toujours fait. Dans d'autres situations on peut vouloir exprimer un conjonction de conditions où chaque la condition doit être évalué (a sens) que si la précédente condition est satisfaite. Ces deux les choses peuvent se faire avec de court-circuit les formulaires de contrôle de ...

En Algol 60, on peut obtenir l'effet de court-circuit d'évaluation uniquement par utiliser des expressions conditionnelles, depuis l'évaluation complète est effectuée sinon. Cela conduit souvent à des les constructions qui sont pénibles à suivre...

Plusieurs langues ne définissent pas comment boolean conditions doivent être évalué. En conséquence les programmes de basé sur l'évaluation de court-circuit sera ne pas être portable. De toute évidence, cela illustre la nécessité de séparer les les opérateurs booléens de court-circuit les formulaires de contrôle.

4voto

Remus Rusanu Points 159382

Regarde mon exemple à Sur SQL Server opérateur booléen de court-circuit qui montre pourquoi un certain chemin d'accès dans SQL est plus efficace si boolean court-circuit n'est pas utilisé. Mon blog exemple, il montre comment le fait de compter sur boolean court-circuit peut briser votre code si vous assumez de court-circuit en SQL, mais si vous lisez le raisonnement pourquoi est-SQL évaluation de la droite d'abord, vous verrez que c'est correct et ce résultat à un bien meilleur chemin d'accès.

4voto

Steve Wortham Points 11563

Je dirais que 99 fois sur 100, je préfère la version de court-circuiter les opérateurs pour la performance.

Mais il y a deux grandes raisons pour lesquelles j'ai trouvé où je ne les utilise pas. (En passant, mes exemples sont en C où: & & et || sont de court-circuit et & et | ne sont pas.)

1.) Lorsque vous souhaitez appeler deux ou plusieurs fonctions dans une instruction if, indépendamment de la valeur retournée par la première.

if (isABC() || isXYZ()) // short-circuiting logical operator
    //do stuff;

Dans ce cas isXYZ() est appelée uniquement si isABC() renvoie la valeur false. Mais vous pouvez isXYZ() est appelé à n'importe quoi.

Ainsi, au lieu de vous faire ceci:

if (isABC() | isXYZ()) // non-short-circuiting bitwise operator
    //do stuff;

2.) Lorsque vous effectuez boolean mathématiques avec des entiers.

myNumber = i && 8; // short-circuiting logical operator

n'est pas nécessairement la même chose que:

myNumber = i & 8; // non-short-circuiting bitwise operator

Dans cette situation, vous pouvez réellement obtenir des résultats différents en raison du court-circuit de l'opérateur ne sont pas nécessairement évaluer l'expression entière. Et qui le rend pratiquement inutile pour booléenne mathématiques. Donc dans ce cas je serais d'utiliser la non-court-circuit (bit à bit) des opérateurs de la place.

Comme je le laissait présager, ces deux scénarios sont vraiment rare pour moi. Mais vous pouvez le voir il y a de réelles programmation raisons pour les deux types d'opérateurs. Et heureusement, la plupart des langues populaires d'aujourd'hui ont les deux. Même VB.NET a la AndAlso et OrElse de court-circuiter les opérateurs. Si une langue aujourd'hui ne pas avoir les deux, je dirais que c'est derrière la fois et vraiment les limites de la programmeur.

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