C # bytes operation

Can someone please tell me why here:

Byte b = 100; b = (Byte)(b+200); 

I need to use explicit type conversion. But here

 Byte b = 100; b += 200; 

I do not need to do this?

Does the compiler generate different IL code for these two cases? And in which case is better?

+7
source share
4 answers

As the standard allows this (see second case below):

14.14.2 Compound purpose

An operation of the form x op = y processed by applying the overload resolution of binary operators (Β§14.2.4), as if the operation were written x op y . Then

  • If the return type of the selected operator is implicitly converted to type x , the operation evaluates to x = x op y , except that x is evaluated only once.

  • Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly converted to type x , and if y implicitly converted to type x or the operator is a shift operator, then the operation evaluates to x = (T)(x op y) , where T is a type x , except that x is evaluated only once.

  • Otherwise, the compound assignment is invalid and a compile-time error occurs.

In this case, the IL code should be essentially identical. Of course, if an estimate of b has side effects, it will be evaluated twice in the case b = (byte)b + 200 and only once when using the composite assignment.

+14
source

This is the FAQ in the C # tag, it's hard to find a duplicate. First of all, you need a stock. The main reason is that the CLI indicates only a limited number of valid types for the Opcodes.Add IL command. Only operands such as Int32, Int64, Single, Double, and IntPtr are supported. IntPtr is also special, C # prohibits the use of this.

Thus, the C # compiler must use implicit conversion to raise the byte to the type supported by the operator. It will display Int32 as the closest compatible type. The result of the addition is Int32. Which does not fit back into the byte, without trimming the result, discarding the extra bits. An obvious example is 255 + 1, the result is 256 in Int32, but does not match the byte and gives 0 when saved.

In this problem, the language developers did not like the truncation to happen without you, clearly recognizing that you know the consequences. The cast is required to convince the compiler that you know. Of course, a bit of a blacksmith, as a rule, you make castings without thinking about the consequences. But this makes your problem, not Microsoft :)

The cutting operator was the + = operator, a very good operator for writing the compaction code. Compatible with the multiplicity of the var keyword. Scala and a difficult place, however, where did you put the cast? It just doesn't work, so they scared the problem and resolved truncation without casting.

It is known how VB.NET works; it does not require a cast. But it gives a guarantee that C # does not provide a default, it throws an OverflowException when the result does not fit. Pretty nice, but this check does not come for free.

The development of pure languages ​​is a very difficult problem. The C # team did an excellent job, the warts could not stand it. Otherwise, the kind of warts caused by the design of the processor. IL has such type restrictions because it is what real 32-bit processors have, especially in RISC designs that were popular in the 90s. Their internal registers can only process IEEE-754 32-bit integers and floating points. And only smaller types are allowed in loads and shops. The Intel x86 core is very popular and actually allows you to perform basic operations with smaller types. But this is mainly a historical accident due to the fact that Intel supports a design that is compatible with 8-bit 8080 and 16-bit generations of 8086. It does not come for free, 16-bit operations require an additional processor cycle. It should be avoided.

+5
source

This is due to implicit conversion rules.

When you have the binary + operator, the result is converted to the larger of the two types. Literal 200 is of type int and therefore the type of expression b+200 is int. The assignment operator = does not perform an implicit conversion, but rather generates an error. As in

  int x = 10; Byte b = x; //Error 

In the second case, the += operator expects a byte, so 200 (which is of type int but fits in bytes) is implicitly converted to bytes, because the compiler knows what it can. The following will not compile because the compiler does not know whether x will fit in bytes or not.

  Byte b = 100; int x = 200; b += x; //Error 

If you do xa const, it will compile:

  Byte b = 100; const int x = 200; b += x; //OK 
0
source

The specification calls this as a specific case of a complex assignment operator:

http://msdn.microsoft.com/en-us/library/aa691316%28v=vs.71%29.aspx

In particular, bullet 2:

  • Otherwise, if the selected operator is a predefined operator, if the return type of the selected operator is explicitly converted to type x, and if y is implicitly converted to type x, then the operation is evaluated as x = (T) (x op y), where T is the type x, except that x is evaluated only once.

The second rule above allows x op = y to be evaluated as x = (T) (x op y) in certain contexts. The rule exists in such a way that predefined operators can be used as compound operators when the left operand is of the type sbyte, byte, short, ushort or char. Even when both arguments are one of these types, the predefined operators yield an int type result, as described in section 7.2.6.2. Thus, without a throw, it would be impossible to assign the result to the left operand.

0
source

All Articles