OT (partially): about promotion of integers

foobar foo at bar.com
Tue Dec 11 15:44:53 PST 2012


On Tuesday, 11 December 2012 at 22:08:15 UTC, Walter Bright wrote:
> On 12/11/2012 10:44 AM, foobar wrote:
>> All of the above relies on the assumption that the safety 
>> problem is due to the
>> memory layout. There are many other programming languages that 
>> solve this by
>> using a different point of view - the problem lies in the 
>> implicit casts and not
>> the memory layout. In other words, the culprit is code such as:
>> uint a = -1;
>> which compiles under C's implicit coercion rules but _really 
>> shouldn't_.
>> The semantically correct way would be something like:
>> uint a = 0xFFFF_FFFF;
>> but C/C++ programmers tend to think the "-1" trick is less 
>> verbose and "better".
>
> Trick? Not at all.
>
> 1. -1 is the size of an int, which varies in C.
>
> 2. -i means "complement and then increment".
>
> 3. Would you allow 2-1? How about 1-1? (1-1)-1?
>
> Arithmetic in computers is different from the math you learned 
> in school. It's 2's complement, and it's best to always keep 
> that in mind when writing programs.

Thanks for proving my point. after all , you are a C++ developer, 
aren't you? :)
Seriously though, it _is_ a trick and a code smell.
I'm fully aware that computers used 2's complement. I'm also am 
aware of the fact that the type has an "unsigned" label all over 
it. You see it right there in that 'u' prefix of 'int'. An 
unsigned type should semantically entail _no sign_ in its 
operations. You are calling a cat a dog and arguing that dogs 
barf? Yeah, I completely agree with that notion, except, we are 
still talking about _a cat_.

To answer you question, yes, I would enforce overflow and 
underflow checking semantics. Any negative result assigned to an 
unsigned type _is_ a logic error.
you can claim that:
uint a = -1;
is perfectly safe and has a well defined meaning (well, for C 
programmers that is), but what about:
uint a = b - c;
what if that calculation results in a negative number? What 
should the compiler do? well, there are _two_ equally possible 
solutions:
a. The overflow was intended as in the mask = -1 case; or
b. The overflow is a _bug_.

The user should be made aware of this and should make the 
decision how to handle this. This should _not_ be implicitly 
handled by the compiler and allow bugs go unnoticed.

I think C# solved this _way_ better than C/D. Another data point 
would be (S)ML which is a compiled language which requires 
_explicit conversions_ and has a very strong typing system. Its 
programs are compiled to efficient native executables and the 
strong typing allows both the compiler and the programmer better 
reasoning of the code. Thus programs are more correct and can be 
optimized by the compiler. In fact, several languages are 
implemented in ML because of its higher guaranties.


More information about the Digitalmars-d mailing list