2009-05-07 27 views
7

Situation: vérification de l'état en C++ ou C# avec de nombreux critères:En C++ et C# sont des vérifications de plusieurs conditions effectuées dans une séquence prédéterminée ou aléatoire?

if (condition1 && condition2 && condition3) 
{ 
    // Do something 
} 

J'ai toujours cru la séquence dans laquelle ces contrôles sont effectués ne sont pas garanties. Donc, ce n'est pas nécessairement la première condition1, puis la condition2 et seulement ensuite la condition3. Je l'ai appris à mon époque avec C++. Je pense qu'on me l'a dit ou que je l'ai lu quelque part.

Jusqu'à sais que je l'ai toujours secure code écrit pour tenir compte des pointeurs nuls possibles dans la situation suivante:

if ((object != null) && (object.SomeFunc() != value)) 
{ 
    // A bad way of checking (or so I thought) 
} 

J'écrivais:

if (object != null) 
{ 
    if (object.SomeFunc() != value) 
    { 
     // A much better and safer way 
    } 
} 

Parce que je ne savais pas la La vérification non-null s'exécutera d'abord et seulement ensuite la méthode d'instance sera appelée pour effectuer la deuxième vérification.

Maintenant, nos plus grands esprits de la communauté me disent que la séquence dans laquelle ces contrôles sont effectués est garantie pour fonctionner dans l'ordre de gauche à droite.

Je suis très surpris. Est-ce vraiment le cas pour les langages C++ et C#?

Est-ce que quelqu'un d'autre a déjà entendu la version que j'ai entendue?

+1

Les sous-expressions en C# sont évaluées de gauche à droite, toujours, période. Les sous-expressions en C/C++ sont évaluées dans l'ordre des points de séquence. Deux expressions dans le même point de séquence peuvent être évaluées dans n'importe quel ordre. Faites une recherche sur le web sur "point de séquence" si vous avez besoin d'une définition formelle. –

Répondre

14

La réponse courte est de gauche à droite avec évaluation de court-circuit. L'ordre est prévisible.

// perfectly legal and quite a standard way to express in C++/C# 
if(x != null && x.Count > 0) ... 

Certaines langues évaluent tout dans l'état avant la ramification (VB6 par exemple).

// will fail in VB6 if x is Nothing. 
If x Is Not Nothing And x.Count > 0 Then ... 

Réf: MSDN C# Operators et leur ordre ou priorité.

+0

@Robert: Ne voulez-vous pas dire "Si x n'est pas Nothing && ..." (ou syntaxe VB6 équivalente)? – RichieHindle

+1

@RichieHindle - oui, mon souvenir de VB6/VBScript est heureusement très vieux. Je vais mettre à jour –

2

Ils sont définis pour être évalués de gauche à droite, et pour arrêter l'évaluation lorsque l'un d'entre eux évalue à faux. C'est vrai aussi bien en C++ qu'en C#.

0

Je ne pense pas qu'il y ait eu ou qu'il y en ait eu d'autre. Ce serait comme si le compilateur décidait d'exécuter des relevés dans le désordre sans raison. :) Maintenant, certains langages (comme VB.NET) ont des opérateurs logiques différents pour court-circuiter et non court-circuiter. Mais, l'ordre est toujours bien défini au moment de la compilation.

Voici la operator precedence de la spécification de langage C#. De la spécification ...

A l'exception des opérateurs d'affectation, tous les opérateurs binaires sont gauche associative, ce qui signifie que opérations sont effectuées de gauche à droite . Par exemple, x + y + z est évalué comme (x + y) + z.

+0

Encore une fois, la précédence, l'associativité et l'ordre de l'évaluation de sous-expression sont trois choses différentes. Vous ne pouvez pas déterminer l'ordre de priorité en C#. –

+0

Aussi, je regrette que la spécification soit mal formulée dans le bit que vous avez cité. J'ai essayé de régler ça. –

+0

Oui, je vois ce que vous voulez dire. C'est contre-intuitif, mais je suppose que l'opération peut être à gauche associative et être toujours évaluée de gauche à droite. Les deux doivent être évalués avant que l'opération puisse être appliquée, donc la précédence n'implique pas nécessairement l'ordre d'évaluation. Mais alors il faudrait abandonner le court-circuit car le court-circuit && ne fonctionnerait pas (forcément) avec deux opérateurs et trois opérandes et || court-circuit ne fonctionnerait pas avec deux. –

0

Ils doivent être exécutés de gauche à droite. Ceci permet à l'évaluation du court-circuit de fonctionner. Pour plus d'informations, reportez-vous au Wikipedia article.