7
votes

Opération d'addition d'octets C #

Quelqu'un pourrait-il me dire, pourquoi ici: xxx

Je dois utiliser une conversion de type explicite. Mais ici xxx

Je n'ai pas besoin de faire cela?

Le compilateur génère un code IL différent pour ces deux cas? Et quel cas est le meilleur?


2 commentaires

De la mémoire, ils sont identiques - avez-vous essayé avec réflecteur / ildasme, cependant?


Je viens de compiler et inspecté avec ildasm.exe et ils sont en fait identiques. Voir la réponse de Mehrdad pour la raison du traitement différent du compilateur.


4 Réponses :


0
votes

Ceci en raison des règles de conversion implicites.

Lorsque vous avez un opérateur binaire + , le résultat est converti en plus grand des deux types. Le littéral 200 est de type INT et donc le type de l'expression B + 200 est int. L'opérateur d'affectation = ne fait pas de conversion implicite, mais plutôt une erreur. Comme dans xxx

dans le second cas, le + = s'attend à des octets, donc 200 (qui est de type INT, mais s'inscrit en octets) est Implicitement converti en octets, car le compilateur le sait que cela peut. Ce qui suit ne sera pas compilé, car la compilée ne sait pas si X ira dans un octet ou non. xxx

Si vous faites XA Cons, alors il compile: xxx


0 commentaires

15
votes

Parce que la standard le permet (voir le deuxième cas ci-dessous):

14.14.2 Assignement composé

une opération du formulaire x op = y est traité en appliquant une résolution de surcharge d'opérateur binaire (§ 14.2.4) Comme si l'opération était écrite x op y . Ensuite,

  • Si le type de retour de l'opérateur sélectionné est implicitement convertible au type de x , l'opération est évaluée sous forme x = x op < / em> y , sauf que x est évalué une seule fois.

  • Sinon, si l'opérateur sélectionné est un opérateur prédéfini, si le type de retour de l'opérateur sélectionné est explicitement convertible sur le type de x , et si y est implicitement convertible au type de x ou que l'opérateur est un opérateur de décalage, alors l'opération est évaluée sous forme x = (t) (x op y) , où t est le type de x , sauf que x est évalué une seule fois. < / p>

  • Sinon, l'affectation des composés n'est pas valide et une erreur de compilation se produit.

    Le code IL doit être essentiellement identique dans ce cas. Bien sûr, si l'évaluation B a des effets secondaires, il sera évalué deux fois dans le boîtier B = (octet) B + 200 et une seule fois lors de l'utilisation d'une affectation composée.


1 commentaires

Merci pour la simplicité de votre réponse!



0
votes

La spécification appelle cela comme cas spécifique de l'opérateur d'affectation composé:

http://msdn.microsoft. Com / fr-US / Bibliothèque / AA691316% 28V = vs.71% 29.aspx

Spécifiquement, BUNLET 2:

  • sinon, si l'opérateur sélectionné est un opérateur prédéfini, si le Le type de retour de l'opérateur sélectionné est explicitement convertible à la type de x, et si y est implicitement convertible au type de x, puis l'opération est évaluée comme x = (t) (x op y), où T est le type de x, sauf que x est évalué une seule fois.

    La deuxième règle ci-dessus permet x op = y à évaluer comme x = (t) (x op y) dans certains contextes. La règle existe de telle que le prédéfini Les opérateurs peuvent être utilisés comme opérateurs de composés lorsque l'opérande gauche est de type Sbyte, octet, court, ushort ou char. Même quand les deux arguments sont de l'un de ces types, les opérateurs prédéfinis produisent un résultat de type INT, comme décrit à la section 7.2.6.2. Ainsi, sans le jeter ne serait pas possible d'attribuer le résultat à l'opérande gauche.


0 commentaires

6
votes

Ceci est une FAQ dans la balise C #, difficile à trouver le duplicata. La nécessité de la distribution est pertinente en premier. La raison sous-jacente est que la CLI spécifie uniquement un nombre limité de types valides pour l'instruction OPCODES.ADD IL. Seuls les opérandes de type INT32, INT64, SIMPLE, DOUBLE et INTPTR sont pris en charge. IntPTR est également spécial, la langue C # interdit l'utilisation de celui-là.

de sorte que le compilateur C # a a utiliser une conversion implicite pour élever l'octet à un type que l'opérateur prend en charge. Il choisira INT32 comme le type compatible le plus proche. Le résultat de l'addition est de 32. Ce qui ne rentre pas dans un octet sans tronquer le résultat, jetant les bits supplémentaires. Un exemple évident est de 255 + 1, le résultat est de 256 en int32 mais ne convient pas à un octet et à un rendement 0 lorsqu'il est stocké.

C'est un problème, les concepteurs de langue n'a pas aimé que la troncature se produise sans que vous reconnaissiez explicitement que vous connaissez les conséquences. Un casting est tenu de convaincre le compilateur que vous êtes au courant. Un peu d'une flexité bien sûr, vous avez tendance à produire le casting mécaniquement sans penser beaucoup aux conséquences. Mais cela en fait votre problème, pas Microsoft :)

Le frottement était l'opérateur + =, un très bel opérateur à écrire Condense Code. Ressemble à la brièveté du mot clé var . Rock et une place difficile cependant, où mettez-vous le casting? Cela ne fonctionne tout simplement pas, alors ils pontent le problème et ont permis de troncature sans couler.

Nottable est la façon dont vb.net fonctionne, il ne nécessite pas de couler. Mais il garantit une garantie que c # ne fournit pas par défaut, il générera une exception overflowException lorsque le résultat ne convient pas. Jolie belle, mais ce chèque ne vient pas gratuitement.

Conception de langues propres est un problème très difficile. L'équipe C # a fait un excellent travail, les verrues ne se dent pas. Sinon, le genre de verrues apportées par la conception du processeur. Il a ces restrictions de type car c'est ce que les vrais processeurs de 32 bits ont également, en particulier les conceptions de RISC populaires dans les années 90. Leurs registres internes ne peuvent gérer que des entiers 32 bits et le point flottant IEEE-754. Et permettre uniquement de petits types de charges et de magasins. Le noyau Intel X86 est très populaire et permet d'opérations de base sur des types plus petits. Mais c'est surtout un accident historique en raison de l'Intel qui maintient la conception compatible grâce aux générations 8080 et 16 bits 8 bits 8086. Cela ne vient pas gratuitement, les opérations de 16 bits coûte un cycle supplémentaire de la CPU. Être évité.


0 commentaires