Reputation: 3092
public void Foo(double d){
// when called below, d == 2^32-1
...
}
public void Bar(){
uint ui = 1;
Foo( 0 - ui );
}
I would expect both 0 and ui to be promoted to signed longs here.
True, with the 0 literal it is knowable at compile time that a cast to uint is safe,
but I suppose this all just seems wrong. At least a warning should be issued.
Thanks!
Does the language spec cover a semi-ambiguous case like this?
Upvotes: 4
Views: 4263
Reputation: 1502126
Why would anything be promoted to long
? The spec (section 7.8.5) lists four operators for integer subtraction:
int operator-(int x, int y);
uint operator-(uint x, uint y);
long operator-(long x, long y);
ulong operator-(ulong x, ulong y);
Given that the constant value 0
is implicitly convertible to uint
, but the uint
value ui
is not implicitly convertible to int
, the second operator is chosen according to the binary operator overload resolution steps described in section 7.3.4.
(Is it possible that you were unaware of the implicit constant expression conversion from 0
to uint
and that that was the confusing part? See section 6.1.9 of the C# 4 spec for details.)
Following section 7.3.4 (which then refers to 7.3.5, and 7.5.3) is slightly tortuous, but I believe it's well-defined, and not at all ambiguous.
If it's the overflow that bother you, would expect this to fail as well?
int x = 10;
int y = int.MaxValue - 5;
int z = x + y;
If not, what's really the difference here?
Upvotes: 7
Reputation: 8511
In a checked context, if the difference is outside the range of the result type, a System.OverflowException is thrown. In an unchecked context, overflows are not reported and any significant high-order bits outside the range of the result type are discarded.
http://msdn.microsoft.com/en-us/library/aa691376(v=vs.71).aspx
Technically, doing the following:
double d = checked(0-ui);
Will result in a throw of System.OverflowException
which is perhaps what you are expecting, but according to the spec since this is not checked the overflow is not reported.
Upvotes: 0
Reputation: 2179
It's the int
that is being cast to uint
to perform substraction from 0 (which is implicitly interpreted by the compiler as uint
). Note that int
to uint
is an implicit conversion hence no warning. There is nothing wrong with your code... except that uint
is not CLS-compilant. You can read why here. More info on CLS-compilant code on MSDN
Upvotes: 0