7
votes

C #: Ordonnance d'évaluation de la fonction (vs c)

Prendre le code C suivant ( k & r pg. 77 ): xxx

Le livre dit que depuis - et / ne sont pas des opérateurs commutatifs, l'ordre dans lequel les fonctions 2 POP sont évaluées sont nécessaires (évidemment, pour obtenir le résultat correct) ... et vous devez donc mettre le résultat de La première fonction d'une variable d'abord, puis procédez à l'arithmétique, comme telle: xxx

apparemment, c'est parce que le compilateur ne peut garantir dans quelle commande les fonctions sont évaluées ( ... Pourquoi?)


Ma question est, est-ce que c # faire cette même chose? Comme dans, dois-je m'inquiéter de ce genre de chose en travaillant avec C #? Et pour cette affaire, l'une des autres langues de niveau supérieur?


2 commentaires

Quant à la raison pour laquelle, permettant au compilateur C d'évaluer l'un ou l'autre côté est d'abord permis de mieux optimiser le code de langue de la machine qu'il a généré. Vous pouvez déjà avoir une variable du côté droit de votre équation dans un registre et souhaitez l'utiliser en premier. Avec les processeurs multi-cachettes multi-cachettes, même en veillant à une ligne après une autre nécessité une attention délibérée ...


FWIW, vous pouvez trouver votre chemin vers la spécification C # ici: MSDN.MicRosoft.com /en-us/library/ms228593.aspx Ce n'est pas trop long, et pas terriblement obtus. :)


8 Réponses :


11
votes

en C # Il est laissé à droite: http: // blogs.msdn.com/oldnewthing/archive/2007/08/14/43742222.aspx


re: commandez C ++

Apparemment, c'est parce que le compilateur ne peut garantir dans quelle commande les fonctions sont évaluées (... pourquoi?)

Tout compilateur particulier peut garantir la commande. Le problème est que la spécification de langue ne spécifie pas de commande, chaque compilateur peut donc faire ce qu'il veut. Cela signifie que vous devez ajouter un point de séquence entre les deux appels de méthode si vous souhaitez garantir la commande.


0 commentaires

1
votes

L'ordre d'évaluation est bien défini en C # dans tous les cas et est de gauche à droite. De C # Spec (§7.3):

L'ordre d'évaluation des opérateurs dans une expression est déterminé par la préséance et l'association des opérateurs (§7.2.1). Les opérandes dans une expression sont évaluées de gauche à droite. Par exemple, en F (I) + g (i ++) * H (i), la méthode F est appelée à l'aide de l'ancienne valeur de i, puis la méthode G est appelée à l'ancienne valeur de i et, enfin, la méthode h est appelée. avec la nouvelle valeur de i. Ceci est séparé et indépendant de la préséance de l'opérateur

Dans le cas de C ++, ce n'est pas que l'ordre ne pouvait pas être défini; C'est que permettre à l'ordre d'être indéfini permet au compilateur de mieux optimiser le code.


0 commentaires

0
votes

Je crois en C # La liste des arguments est évaluée dans l'ordre, de gauche à droite.


0 commentaires

2
votes

de fabuleuses aventures Dans le codage: precedence vs associativité vs ordre :

Une autre façon de regarder c'est que la règle en C # n'est pas "fait les parenthèses d'abord", mais plutôt de la parenthèse de tout, appliquez de manière récursive la règle "Évaluez le côté gauche, puis évaluez le côté droit, puis effectuez l'opération ".


0 commentaires

0
votes

Couleur me surprise, mais apparemment C # fait la chose "droite" et évalue de gauche à droite: xxx


3 commentaires

Pendant que vous avez raison dans ce cas, ne tombez pas dans le piège des tests qui montrent «cela fonctionne pour moi» de répondre à ces types de questions - il est tout à fait possible qu'un compilateur C donne le même résultat, mais vous le feriez être incorrect de supposer que cela signifiait avait pour donner ce résultat.


Considérant qu'il n'y ait que deux compilateurs C # C # (CSC de Microsoft et Mono), ce n'est pas si important, cependant, comparé la véritable PlayeDora des compilateurs C / C ++.


Premier no: il y a au moins trois compilateurs C # je suis au courant de (Dotgnu). Deuxièmement Non: le nombre de compilateurs C # très limités et pour eux, quelque chose est vrai, que quelque chose - vrai n'est qu'un test, pas une preuve. Je suis tout à fait d'accord avec Michael Burr, "Travailler pour moi" est annulé, même si ce n'est pas une grosse affaire dans ce cas.



2
votes

Non, c # ne fait pas la même chose. Il n'utilise pas les limites d'évaluation de la même manière que c, où l'ordre d'exécution entre les limites est indéfini. L'expression est évaluée de gauche à droite, tout comme vous l'attendez.

Si vous êtes toujours incertain de l'ordre d'exécution ou si vous souhaitez effectuer le code plus clair, vous devez utiliser une variable locale pour un résultat intermédiaire. Les variables locales sont très bon marché pour allouer, car elles sont allouées sur la pile et, dans certains cas, le compilateur est même capable de mettre la variable dans un registre afin de ne pas être alloué du tout. En outre, en fonction de la façon dont l'expression semble que le compilateur peut avoir besoin d'utiliser une variable locale pour stocker le résultat intermédiaire de toute façon.


0 commentaires

5
votes

Pour répondre à votre question sur la raison pour laquelle C ne définit pas l'ordre de fonctionnement, c'est simplement parce que les inventeurs de C ont décidé qu'il serait utile de donner à la mise en œuvre du compilateur la possibilité d'optimiser l'évaluation de l'expression. Ils ont également décidé que c'était plus précieux que de donner à la sécurité des programmeurs dans l'évaluation de l'expression.

N'oubliez pas que lorsque C a été développé à l'origine, les machines étaient beaucoup moins capables qu'aujourd'hui, et il y avait plus d'intérêt à donner aux compilateurs la marge de manœuvre d'optimisation. Aujourd'hui, il y a souvent plus de poids donné à un code plus sûr et plus prédicatif.


1 commentaires

Outre le changement d'importance entre performance vs prévisibilité (qui a beaucoup à voir avec le passage du coût majeur du coût de l'opération de l'informatique au salaire du programmeur), on a également fait remarquer que les cas où il a fait une différence significative était déjà autorisée car Le compilateur pourrait facilement prouver qu'il n'y avait pas de différences comportementales.



1
votes

Le livre dit que depuis - et / ne sont pas des opérateurs de commutatifs, l'ordre dans lequel les 2 fonctions pop sont évaluées est nécessaire (évidemment, pour obtenir le résultat correct) ... et vous devez donc mettre le résultat de la première fonction dans une variable d'abord puis procédez à l'arithmétique.

Ce n'est pas tout à fait correct. K & R Réaménagement autorisé des opérateurs de commutation ( Donné à l'ANSI C ). Puisque suibtraction est pas commutative, il n'est pas réagissant ... sous cette règle, au moins.

(Un) heureusement, c ne pas Définissez l'ordre de l'évaluation (en dehors de une portée assez petite ) - ce qui signifie que le compilateur peut appeler ces fonctions dans n'importe quel ordre (aussi longtemps À la suite de POP () - POP () est entièrement évalué avant d'appeler push () )

qui - dans ce cas, entraîne le même problème - mais pour une raison différente.


0 commentaires