2010-09-03 9 views
17

de OK, je suis un peu embarrassée de poser cette question, mais je veux juste être sûr ...évaluation court-circuit et les effets secondaires

On sait que C utilise l'évaluation de court-circuit dans les expressions booléennes:

int c = 0; 
if (c && func(c)) { /* whatever... */ } 

Dans cet exemple func(c) n'est pas appelé parce que c est évaluée à 0. Mais qu'en est-il de l'exemple plus sophistiqué où les effets secondaires de la comparaison changeraient la variable comparée ensuite? Comme ceci:

int c; /* this is not even initialized... */ 
if (canInitWithSomeValue(&c) && c == SOMETHING) { /*...*/ } 

Fonction canInitWithSomeValue renvoie true et la valeur change au pointeur donné en cas de succès. Est-il garanti que les comparaisons suivantes (c == SOMETHING dans cet exemple) utilisent la valeur définie par canInitWithSomeValue(&c)?

Quelle que soit l'ampleur des optimisations utilisées par le compilateur?

+0

Je pense que vous pourriez confondre l'évaluation de court-circuit et l'optimisation du compilateur. Dans le premier exemple, le compilateur optimisera toute l'instruction 'if', car il ne pourra jamais s'exécuter. Le court-circuit d'évaluation signifierait que si vous aviez 'if (func1() && func2()) {...}', et func1() évalué à false ** à l'exécution ** (c'est-à-dire pas définitivement lors de la compilation), alors le code ne devrait pas vérifier 'func2()' - le compilateur aurait dû créer le code machine de sorte que si 'func1()' est faux, 'func2()' ne soit pas appelé. – Stephen

+0

Que 'int c = 0' était là pour indiquer que 'c' est égal à' 0' au moment de la comparaison, je me rends compte que dans un cas aussi simple que le compilateur optimisera tout 'if'. –

+0

Ah, je m'excuse. Je vous ai mal lu. Mes excuses. – Stephen

Répondre

23

Est-il garanti que les comparaisons ultérieures (c == quelque chose dans cet exemple) utilise la valeur définie par canInitWithSomeValue (& c)?

Oui. Parce qu'il ya une sequence point

Entre évaluation des opérandes de gauche et de droite de la && (logique), || (logique) et les opérateurs par des virgules. Par exemple, dans l'expression *p++ != 0 && *q++ != 0, tous les effets secondaires de la sous-expression * p ++! = 0 sont terminés avant toute tentative d'accès à q.


Un point de la séquence définit un point quelconque dans une exécution de programme d'ordinateur à laquelle il est garanti que tous les effets secondaires des évaluations précédentes auront été effectuées, et aucun effet secondaire à partir des évaluations ultérieures ont encore été effectuée .

+0

bonne réponse, merci! –

5

Oui. Parce que les opérateurs && et || sont aussi des éléments appelés points de séquence. Ces derniers définissent quand les effets secondaires d'une opération précédente devraient être terminés et ceux du suivant n'auraient pas dû commencer.

1

L'évaluation dans la condition composite d'instruction if est strictement de gauche à droite. La seule circonstance sous laquelle le second test de votre if serait optimisé est si le compilateur peut déterminer avec une certitude de 100% que le premier est identique à false.

Questions connexes