Jump to page: 1 2
Thread overview
Why do I have to cast arguments from int to byte?
Oct 10, 2017
Chirs Forest
Oct 10, 2017
Moritz Maxeiner
Oct 10, 2017
Igor Shirkalin
Oct 10, 2017
Adam D. Ruppe
Oct 11, 2017
rjframe
Oct 11, 2017
Daniel Kozak
Oct 12, 2017
kdevel
Oct 13, 2017
Daniel Kozak
Oct 13, 2017
Daniel Kozak
Oct 13, 2017
kdevel
October 10, 2017
I keep having to make casts like the following and it's really rubbing me the wrong way:

void foo(T)(T bar){...}

byte bar = 9;

foo!byte(bar + 1); //Error: function foo!byte.foo (byte bar) is not callable using argument types (int)	
foo!byte(cast(byte)(bar + 1));

It wouldn't be so bad if I didn't have to use the word cast before each cast, bust since I have to specify both the word cast and the cast type and then wrap both the cast type and the value in brackets... it just explodes my code into multiple lines of unreadable mess.


void foo(T)(T bar, T bar2, T bar3){...}

byte foobar = 12;

foo!byte(foobar + 1, foobar + 22, foobar + 333);
vs.
foo!byte(cast(byte)(foobar + 1), cast(byte)(foobar + 22), cast(byte)(foobar + 333));

Why?
October 10, 2017
On Tuesday, 10 October 2017 at 19:55:36 UTC, Chirs Forest wrote:
> I keep having to make casts like the following and it's really rubbing me the wrong way:
>
> void foo(T)(T bar){...}
>
> byte bar = 9;
>
> [...]
>
> Why?

Because of integer promotion [1], which is inherited from C.

[1] https://dlang.org/spec/type.html#integer-promotions
October 10, 2017
On Tuesday, 10 October 2017 at 19:55:36 UTC, Chirs Forest wrote:
> I keep having to make casts like the following and it's really rubbing me the wrong way:
>
> void foo(T)(T bar){...}
>
> byte bar = 9;
>
> foo!byte(bar + 1); //Error: function foo!byte.foo (byte bar) is not callable using argument types (int)	
> foo!byte(cast(byte)(bar + 1));
>
> It wouldn't be so bad if I didn't have to use the word cast before each cast, bust since I have to specify both the word cast and the cast type and then wrap both the cast type and the value in brackets... it just explodes my code into multiple lines of unreadable mess.
>
>
> void foo(T)(T bar, T bar2, T bar3){...}
>
> byte foobar = 12;
>
> foo!byte(foobar + 1, foobar + 22, foobar + 333);
> vs.
> foo!byte(cast(byte)(foobar + 1), cast(byte)(foobar + 22), cast(byte)(foobar + 333));
>
> Why?

Because int (1) + ubyte (9) = int

October 10, 2017
On Tuesday, 10 October 2017 at 19:55:36 UTC, Chirs Forest wrote:
> Why?

D inherited a silly rule from C where any arithmetic is promoted to int first.

The big difference is D doesn't do implicit narrowing conversion... so x + 1 becomes int, but then int to byte requires an explicit cast (unless the compiler can prove the range in that particular expression - this is called "value range propagation").

I think it has proved to be a bit of a mistake :(
October 11, 2017
On Tue, 10 Oct 2017 19:55:36 +0000, Chirs Forest wrote:

> It wouldn't be so bad if I didn't have to use the word cast before each cast, bust since I have to specify both the word cast and the cast type and then wrap both the cast type and the value in brackets... it just explodes my code into multiple lines of unreadable mess.
> 
> 
> void foo(T)(T bar, T bar2, T bar3){...}
> 
> byte foobar = 12;
> 
> foo!byte(foobar + 1, foobar + 22, foobar + 333);
> vs.
> foo!byte(cast(byte)(foobar + 1), cast(byte)(foobar + 22),
> cast(byte)(foobar + 333));


You could wrap the cast in a function to clean it up a bit:

void main() {
    byte foobar = 12;
    foo!byte((foobar + 1).b, (foobar + 22).b, (foobar + 333).b);
}

byte b(int n) pure {
    pragma(inline, true); // Probably not necessary.
    return cast(byte)n;
}

void foo(T)(T bar, T bar2, T bar3) {
    import std.stdio : writeln;
    import std.string : format;
    writeln("%s, %s, %s".format(bar, bar2, bar3));
}


--Ryan
October 11, 2017
You can avoid cast:

void foo(T)(T bar){...}

byte bar = 9;

foo!byte(bar + byte(1));

or

byte bar = 9;
byte num = 1;
foo!byte(bar + num);



On Tue, Oct 10, 2017 at 9:55 PM, Chirs Forest via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:

> I keep having to make casts like the following and it's really rubbing me the wrong way:
>
> void foo(T)(T bar){...}
>
> byte bar = 9;
>
> foo!byte(bar + 1); //Error: function foo!byte.foo (byte bar) is not
> callable using argument types (int)
> foo!byte(cast(byte)(bar + 1));
>
> It wouldn't be so bad if I didn't have to use the word cast before each cast, bust since I have to specify both the word cast and the cast type and then wrap both the cast type and the value in brackets... it just explodes my code into multiple lines of unreadable mess.
>
>
> void foo(T)(T bar, T bar2, T bar3){...}
>
> byte foobar = 12;
>
> foo!byte(foobar + 1, foobar + 22, foobar + 333);
> vs.
> foo!byte(cast(byte)(foobar + 1), cast(byte)(foobar + 22),
> cast(byte)(foobar + 333));
>
> Why?
>


October 12, 2017
On Wednesday, 11 October 2017 at 07:09:26 UTC, Daniel Kozak wrote:
> You can avoid cast:
>
> void foo(T)(T bar){...}
>
> byte bar = 9;
>
> foo!byte(bar + byte(1));

Sure?
---
void foo(T)(T bar)
{
}
byte bar = 9;
void main ()
{
   foo!byte(bar + byte(1));
}
---
byte2.d(7): Error: function byte2.foo!byte.foo (byte bar) is not callable using argument types (int)


October 13, 2017
Not sure :), I have forgoten byte+byte=int.

On Thu, Oct 12, 2017 at 10:51 PM, kdevel via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:

> On Wednesday, 11 October 2017 at 07:09:26 UTC, Daniel Kozak wrote:
>
>> You can avoid cast:
>>
>> void foo(T)(T bar){...}
>>
>> byte bar = 9;
>>
>> foo!byte(bar + byte(1));
>>
>
> Sure?
> ---
> void foo(T)(T bar)
> {
> }
> byte bar = 9;
> void main ()
> {
>    foo!byte(bar + byte(1));
> }
> ---
> byte2.d(7): Error: function byte2.foo!byte.foo (byte bar) is not callable
> using argument types (int)
>
>
>


October 13, 2017
but it works ok with immutable, so until you really need to change bar you can use

immutable bar = 9;
foo!byte(bar + 1);

On Fri, Oct 13, 2017 at 9:46 AM, Daniel Kozak <kozzi11@gmail.com> wrote:

> Not sure :), I have forgoten byte+byte=int.
>
> On Thu, Oct 12, 2017 at 10:51 PM, kdevel via Digitalmars-d-learn < digitalmars-d-learn@puremagic.com> wrote:
>
>> On Wednesday, 11 October 2017 at 07:09:26 UTC, Daniel Kozak wrote:
>>
>>> You can avoid cast:
>>>
>>> void foo(T)(T bar){...}
>>>
>>> byte bar = 9;
>>>
>>> foo!byte(bar + byte(1));
>>>
>>
>> Sure?
>> ---
>> void foo(T)(T bar)
>> {
>> }
>> byte bar = 9;
>> void main ()
>> {
>>    foo!byte(bar + byte(1));
>> }
>> ---
>> byte2.d(7): Error: function byte2.foo!byte.foo (byte bar) is not callable
>> using argument types (int)
>>
>>
>>
>


October 13, 2017
On Friday, 13 October 2017 at 07:47:55 UTC, Daniel Kozak wrote:
> but it works ok with immutable, so until you really need to change bar you can use
>
> immutable bar = 9;
> foo!byte(bar + 1);

As Adam wrote two days ago: 'D doesn't do implicit narrowing conversion... so x + 1 becomes int, but then int to byte requires an explicit cast (unless the compiler can prove the range in that particular expression - this is called "value range propagation").'

« First   ‹ Prev
1 2