Is normal arithmetic conversion the best set of rules?

Consider the following code:

void f(byte x) {print("byte");}
void f(short x) {print("short");}
void f(int x) {print("int");}

void main() {
    byte b1, b2;
    short s1, s2;

    f(b1 + b2); // byte + byte = int
    f(s1 + s2); // short + short = int
}

      

In C ++, C #, D and Java, both function calls resolve "int" overloads ... I already understand it's "in the specs", but why did languages ​​develop this way? I'm looking for a deeper reason.

It makes sense to me that the result is the smallest type capable of representing all possible values ​​of both operands, e.g .:

byte + byte --> byte
sbyte + sbyte --> sbyte
byte + sbyte --> short
short + short --> short
ushort + ushort --> ushort
short + ushort --> int
// etc...

      

This will eliminate awkward code like short s3 = (short)(s1 + s2)

, and also IMO more intuitive and understandable.

Is this a leftover legacy from the C days, or are there better reasons for the current behavior?

+1


a source to share


2 answers


Quoting from this MSDN blog post :

byte b = 32; byte c = 240; int i = b + c; // what is i?

In this fantasy world, the value I will be 16! What for? Because the two operands to the + operator are both bytes, so the sum of "b + c" is calculated as a byte, which results in 16 due to integer overflow. (And, as I noted earlier, integer overflow is a new safety vector.)

Similarly,

int j = -b;

will result in j being 224 and not -32 for the same reason.

Is this really what you want?

...

So, no matter how you cut it, you will have to insert annoying casts. Might also have language to err on the safety side (forcing you to insert casts where you know overflow is not a problem) than to be wrong on the silence side (where you may not notice missing videos until your payroll department asks you why their books don't add up at the end of the month).



Also, it's worth noting that adding to these casts only means adding text and nothing more. Once the JIT (or perhaps the static compiler itself) reduces the arithmetic operation to a basic processor instruction, nothing smart happens - just the question of whether the number is treated like int

or byte

.

This is a good question, however ... not at all obvious. Hope that now the reasons are clear to you.

+2


a source


A better set of rules IMHO, if it were stipulated that shift operators can only be used with constant shift values ​​(use shift functions for shift variables), it would be that the results of any arithmetic expression should always be evaluated as if it were processed with maximum a possible signed or unsigned type, provided that they can be guaranteed to be statically guaranteed to give correct results (in the case where the largest signed type may not be sufficient, somewhat complex rules may apply). If shift operands are only allowed for constants, it would be fairly easy to determine at compile time what the greatest value of any operand is, so I don't see a sufficient reason for compilers not to look athow the result of the operator is used when deciding whether to implement the operator.



0


a source







All Articles