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