Runtime: Define overload math operators for types smaller than int

Created on 13 Jun 2018  路  8Comments  路  Source: dotnet/runtime

Note: I posted this issue in C# repo as weel, but if they will not solve it at the compiler level, it can be solved at CoreFX leve, be defining overload math operators for these types:
Why have we to use cast to do basic math operations between bytes, short, and ushort? I think it will make things easier to define overload operators for those types.
For example:

short x = short.MaxValue;
ushort z =x + x;

this code will not even cause an overflow, but C# doesn't accept it. It only accepts:

short x = short.MaxValue;
ushort z =(ushort)(x + x);
api-suggestion area-System.Numerics

Most helpful comment

@MohammadHamdyGhanem, there is no way to guarantee that (x + y) will return an unsigned value and allowing it to implicitly covert will likely result in even more bugs.

All 8 comments

@MohammadHamdyGhanem, there is no way to guarantee that (x + y) will return an unsigned value and allowing it to implicitly covert will likely result in even more bugs.

The C# compiler would also not respect these new custom operators, as it is hardcoded to emit raw IL instead of an op_Add call for these types. They would also not change the behavior due to it being a breaking change.

@tannergooding

there is no way to guarantee that (x + y) will return an unsigned value and allowing it to implicitly covert will likely result in even more bugs.

This is the same when you add two int that can generate an overflow. I onlt gave an example. C# is not resposible of the results, and should only throw an overflow exception.
This is an example tha is impossible to generate an overflow, yet C# refuses it:

            byte x =2;
            byte y = 1;
            ushort z = x + y;

C# should fix this odd behaviour. I feel angery every time I get syntax error about this, and had to add extra casting!

C# should fix this odd behaviour. I feel angery every time I get syntax error about this, and had to add extra casting!

I would suggest opening a bug against the dotnet/csharplang repo.

@MohammadHamdyGhanem I am not sure which APIs exactly you suggest. Can you please describe the API and their usage?
Your first case of ushort = short + short without explicit cast is a very bad idea as @tannergooding mentioned -1 + 0 would silently become ushort.MaxValue.

ushort = byte + byte should not automatically cast either IMO, because it is not clear if the code wants to first cast to ushort and then add (255+255 = 510), or add with byte limitations (incl. underflow) and then cast to ushort (=254).

@karelz
C# Converts operands to int first, so the result is int, which makes a problem to implicitly cast it back to the desired type. So, ushort = byte + byte becomes ```ushort = int'''. This int is safe to be cast to ushort, so I can say: if neither of the two operands is int, it is safe to do implicit cast.
The ushort class can have these operator:

public static ushort implicit operator + (ushort x, ushort y)
   => ushort((int)x + (int)y);

so, ushort = byte + byte should call this operator. There is some work needed on the C# side, to decide to call ushort.OppAdd not byte.OpAdd based of the le4ft hand variable type. This woll make it behave as we expect. If any programmer have anything else in mind, he can do explicit casting.

This int is safe to be cast to ushort

This is not always true, and is therefore not safe to do by default.

The cast exists to ensure you understand the difference in behavior:
```C#
byte x = 255;
byte y = 255;
x += y;

byte z = (byte)(x + y);
```

The discussion is happening in https://github.com/dotnet/csharplang/issues/1624 - adding API to bypass C# features does not look like a good idea.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

v0l picture v0l  路  3Comments

noahfalk picture noahfalk  路  3Comments

omariom picture omariom  路  3Comments

jzabroski picture jzabroski  路  3Comments

GitAntoinee picture GitAntoinee  路  3Comments