Preventing implicit conversion

2015-11-04 Thread ixid via Digitalmars-d-learn
Is there an elegant way of avoiding implicit conversion to int 
when you're using shorter types?


Re: Preventing implicit conversion

2015-11-04 Thread ixid via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
Is there an elegant way of avoiding implicit conversion to int 
when you're using shorter types?


Also does this not seem inconsistent:

ushort a = ushort.max, b = ushort.max;


a += b; // Compiles fine
a = a + b; // Error: cannot implicitly convert expression 
(cast(int)a + cast(int)b) of type int to ushort


Re: Preventing implicit conversion

2015-11-04 Thread Daniel Kozak via Digitalmars-d-learn
V Wed, 04 Nov 2015 14:27:45 +
ixid via Digitalmars-d-learn 
napsáno:

> Is there an elegant way of avoiding implicit conversion to int 
> when you're using shorter types?

http://dlang.org/phobos/std_typecons.html#.Typedef




Re: Preventing implicit conversion

2015-11-04 Thread ixid via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 17:26:04 UTC, Daniel Kozak wrote:

V Wed, 04 Nov 2015 14:27:45 +
ixid via Digitalmars-d-learn 
napsáno:

Is there an elegant way of avoiding implicit conversion to int 
when you're using shorter types?


http://dlang.org/phobos/std_typecons.html#.Typedef


That doesn't appear to prevent implicit conversion. Making two 
bools (or ubytes etc) that are Typedef and adding them together 
still results in an int.


Re: Preventing implicit conversion

2015-11-04 Thread Maxim Fomin via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
Is there an elegant way of avoiding implicit conversion to int 
when you're using shorter types?


Only with library solution. Implicit conversions are built into 
language.


Re: Preventing implicit conversion

2015-11-04 Thread ixid via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 19:09:42 UTC, Maxim Fomin wrote:

On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
Is there an elegant way of avoiding implicit conversion to int 
when you're using shorter types?


Only with library solution. Implicit conversions are built into 
language.


Doesn't that seem rather limiting and unnecessary?


Re: Preventing implicit conversion

2015-11-04 Thread Maxim Fomin via Digitalmars-d-learn

On Wednesday, 4 November 2015 at 21:22:04 UTC, ixid wrote:
On Wednesday, 4 November 2015 at 19:09:42 UTC, Maxim Fomin 
wrote:

On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
Is there an elegant way of avoiding implicit conversion to 
int when you're using shorter types?


Only with library solution. Implicit conversions are built 
into language.


Doesn't that seem rather limiting and unnecessary?


Well, indeed it often produces confusion (this is inherited from 
C for compatibility purpose).


Re: Preventing implicit conversion

2015-11-04 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, November 04, 2015 21:22:02 ixid via Digitalmars-d-learn wrote:
> On Wednesday, 4 November 2015 at 19:09:42 UTC, Maxim Fomin wrote:
> > On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
> >> Is there an elegant way of avoiding implicit conversion to int
> >> when you're using shorter types?
> >
> > Only with library solution. Implicit conversions are built into
> > language.
>
> Doesn't that seem rather limiting and unnecessary?

Why? You can't affect what conversions do and don't work for the built-in
types in _any_ language that I've ever used, and I've never heard of a
language that allowed anything like that. If you want different conversion
rules, you need to create a user-defined type that defines the conversions
you want. That's pretty normal.

And AFAIK, there aren't very many folks trying to avoid the built-in
implicit conversions in D, particularly since D eliminated the various
implicit narrowing conversions that you get in C/C++.

- Jonathan M Davis



Re: Preventing implicit conversion

2015-11-05 Thread ixid via Digitalmars-d-learn
On Thursday, 5 November 2015 at 05:41:46 UTC, Jonathan M Davis 
wrote:
On Wednesday, November 04, 2015 21:22:02 ixid via 
Digitalmars-d-learn wrote:
On Wednesday, 4 November 2015 at 19:09:42 UTC, Maxim Fomin 
wrote:

> On Wednesday, 4 November 2015 at 14:27:49 UTC, ixid wrote:
>> Is there an elegant way of avoiding implicit conversion to 
>> int when you're using shorter types?

>
> Only with library solution. Implicit conversions are built 
> into language.


Doesn't that seem rather limiting and unnecessary?


Why? You can't affect what conversions do and don't work for 
the built-in types in _any_ language that I've ever used, and 
I've never heard of a language that allowed anything like that. 
If you want different conversion rules, you need to create a 
user-defined type that defines the conversions you want. That's 
pretty normal.


And AFAIK, there aren't very many folks trying to avoid the 
built-in implicit conversions in D, particularly since D 
eliminated the various implicit narrowing conversions that you 
get in C/C++.


- Jonathan M Davis


In C++ I can add two shorts together without having to use a cast 
to assign the result to one of the two shorts. It just seems 
super clunky not to be able to do basic operations on basic types 
without casts everywhere.


Re: Preventing implicit conversion

2015-11-05 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn

On Thursday, 5 November 2015 at 09:33:40 UTC, ixid wrote:

In C++ I can add two shorts together without having to use a 
cast to assign the result to one of the two shorts. It just 
seems super clunky not to be able to do basic operations on 
basic types without casts everywhere.


+1
If automatic shrink is droped from the C legacy stuff, so 
interger propagation should also be dropped (or changed to 
propagate no further than to the actual size of a type). D has a 
far better type system, throw away bad old C habits!


-> this would also make the defect comparison of signed to 
unsigned types visible for small types and hopefully force the 
introduction of the correct comparison!


Re: Preventing implicit conversion

2015-11-05 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn
And I want to have small number litterals automatically choosing 
the smallest fitting type.


If I write

ubyte b = 1u;
auto c = b + 1u;

I expect the 1u to be of type ubyte - and also c.



Re: Preventing implicit conversion

2015-11-05 Thread Adam D. Ruppe via Digitalmars-d-learn
On Thursday, 5 November 2015 at 10:07:30 UTC, Dominikus Dittes 
Scherkl wrote:
And I want to have small number litterals automatically 
choosing the smallest fitting type.


It does, that's the value range propagation at work. Inside one 
expression, if the compiler can prove it fits in a smaller type, 
the explicit cast is not necessary.


ubyte a = 255; // allowed, despite 255 being an int literal
ubyte b = 253L + 2L; // allowed, though I used longs there
ubyte c = 255 + 1; // disallowed, 256 doesn't fit


However, the key there was "in a single expression". If you break 
it into multiple lines with runtime values, the compiler assumes 
the worst:



int i = 254;
int i2 = 1;

ubyte a2 = i + i2; // won't work because it doesn't realize the 
values



But, adding some constant operation can narrow it back down:

ubyte a3 = (i + i2) & 0xff; // but this does because it knows 
anything & 0xff will always fit in a byte



ubyte b = 1u;
auto c = b + 1u;

I expect the 1u to be of type ubyte - and also c.


This won't work because of the one-expression rule. In the second 
line, it doesn't know for sure what b is, it just knows it is 
somewhere between 0 and 255. So it assumes the worst, that it is 
255, and you add one, giving 256... which doesn't fit in a byte. 
It requires the explicit cast or a &0xff or something like that 
to make the bit truncation explicit.




I agree this can be kinda obnoxious (and I think kinda pointless 
if you're dealing with explicitly typed smaller things 
throughout) but knowing what it is actually doing can help a 
little.


Re: Preventing implicit conversion

2015-11-05 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn

On Thursday, 5 November 2015 at 13:23:34 UTC, Adam D. Ruppe wrote:
On Thursday, 5 November 2015 at 10:07:30 UTC, Dominikus Dittes 
Scherkl wrote:



ubyte b = 1u;
auto c = b + 1u;

I expect the 1u to be of type ubyte - and also c.


This won't work because of the one-expression rule. In the 
second line, it doesn't know for sure what b is, it just knows 
it is somewhere between 0 and 255. So it assumes the worst, 
that it is 255, and you add one, giving 256... which doesn't 
fit in a byte.
That would be fine - but c is not ushort (which the worst-case 
256 would fit in), not even uint, but int! A signed type! Just 
because of the crazy C interger propagation rules!
And, ok, one needs to accept that auto may not do exactly what I 
wish for, but if I give an exact type that is likely to fit (and 
has to if all operands are of the same type), I expect it to work 
without extra casts:


ubyte d = b + 1u; // doesn't compile
ubyte d = b + (ubyte)1; // works - and overflows to 0 if b is 255


Re: Preventing implicit conversion

2015-11-05 Thread Dominikus Dittes Scherkl via Digitalmars-d-learn
On Thursday, 5 November 2015 at 22:15:46 UTC, Dominikus Dittes 
Scherkl wrote:
On Thursday, 5 November 2015 at 13:23:34 UTC, Adam D. Ruppe 
wrote:
On Thursday, 5 November 2015 at 10:07:30 UTC, Dominikus Dittes 
Scherkl wrote:



ubyte d = b + (ubyte)1;

Sorry, should of course be:

ubyte d = b + ubyte(1);

Too much C lately :-/


Re: Preventing implicit conversion

2015-11-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, November 05, 2015 09:33:39 ixid via Digitalmars-d-learn wrote:
> In C++ I can add two shorts together without having to use a cast
> to assign the result to one of the two shorts. It just seems
> super clunky not to be able to do basic operations on basic types
> without casts everywhere.

That's why we have value range propagation - so that when the compiler can
prove that the result will fit in the smaller type, it'll let you assign to
it. Perhaps the compiler should do more with that than it currently does,
but it's definitely help reduce the number of casts that are required for
narrowing conversions.

But allowing implicit narrowing conversions is a source of bugs, which is
why languages like D, C#, and Java have all made narrowing conversions
illegal without a cast. Yes, that can be annoying when you need to do math
on a byte or short, and you want the result to end up in a byte or short,
but it prevents bugs. It's a tradeoff. Fortunately, VPR improves the
situation, but we're not going to be able to prevent narrowing bugs while
still allowing implicit narrowing conversions. C/C++ went the route that
requires fewer casts but more easily introduces bugs, whereas D, Java, and
C# went the route where it's harder to introduce bugs but doing arithmetic
on types smaller than int gets a bit annoying. Personally, I think that the
route that D has taken is the better one, but it is a matter of opinion and
priorities.

But if it's important enough to you to not need to cast for arithmetic
operations on small integer types, you can always create a wrapper type that
does all of the casts for you so that you get the implicit conversions.

- Jonathan M Davis