size_t index=-1;

Steven Schveighoffer via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Mar 18 07:51:34 PDT 2016


On 3/17/16 6:46 PM, tsbockman wrote:
> On Thursday, 17 March 2016 at 17:09:46 UTC, Steven Schveighoffer wrote:
>> Converting unsigned to signed or vice versa (of the same size type) is
>> safe. No information is lost.
>
> Saying that "no information is lost" in such a case, is like saying that
> if I encrypt my hard drive and then throw away the password, "no
> information is lost". Technically this is true: the bit count is the
> same as it was before.

It's hard to throw away the "key" of 2's complement math.

> In practice, though, the knowledge of how information is encoded is
> essential to actually using it.

In practice, a variable that is unsigned or signed is expected to behave 
like it is declared. I don't think anyone expects differently.

When I see:

size_t x = -1;

I expect x to behave like an unsigned size_t that represents -1. There 
is no ambiguity here. Where it gets confusing is if you didn't mean to 
type size_t. But the compiler can't know that.

When you start doing comparisons, then ambiguity creeps in. The behavior 
is well defined, but not very intuitive. You can get into trouble even 
without mixing signed/unsigned types. For example:

for(size_t i = 0; i < a.length - 1; ++i)

This is going to crash when a.length == 0. Better to do this:

for(size_t i = 0; i + 1 < a.length; ++i)

unsigned math can be difficult, there is no doubt. But we can't just 
disable it, or disable unsigned conversions.

> In the same way, using `cast(ulong)` to pass `-1L` to a function that
> expects a `ulong` results in a de-facto loss of information, because
> that `-1L` can no longer distinguished from `ulong.max`, despite the
> fundamental semantic difference between the two.

Any time you cast a type, the original type information is lost. But in 
this case, no bits are lost. In this case, the function is declaring "I 
don't care what your original type was, I want to use ulong". If it 
desires to know the original type, it should use a template parameter 
instead.

Note, I have made these mistakes myself, and I understand what you are 
asking for and why you are asking for it. But these are bugs. The user 
is telling the compiler to do one thing, and expecting it to do 
something else. It's not difficult to fix, and in fact, many lines of 
code are written specifically to take advantage of these rules. This is 
why we cannot remove them. The benefit is not worth the cost.

>> VRP on steroids would be nice, but I don't think it's as trivial to
>> solve.
>
> D's current VRP is actually surprisingly anemic: it doesn't even
> understand integer comparisons, or the range restrictions implied by the
> predicate when a certain branch of an `if` statement is taken.
>
> Lionello Lunesu made a PR a while back that adds these two features, and
> it makes the compiler feel a lot smarter. (The PR was not accepted at
> the time, but I have since revived it:
>      https://github.com/D-Programming-Language/dmd/pull/5229)

I'm not compiler-savvy enough to have an opinion on the PR, but I think 
more sophisticated VRP would be good.

-Steve


More information about the Digitalmars-d-learn mailing list