www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - ushort + ushort = int?

reply Andrey <saasecondbox yandex.ru> writes:
Hello,
Here is a code that you can execute using online compiler 
https://run.dlang.io/:

import std.stdio;
void main()
{
    ushort first = 5;
    ushort second = 1000;
 
    ushort result = first + second;
 
    writeln(result);
}
I hae this error:
 onlineapp.d(7): Error: cannot implicitly convert expression 
 cast(int)first + cast(int)second of type int to ushort
Why they are "int" when I declared them as "ushort"??? ushort + ushort = ushort, not int. In C++ there aren't any such issues...
Aug 20 2018
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 20/08/2018 8:34 PM, Andrey wrote:
 Hello,
 Here is a code that you can execute using online compiler 
 https://run.dlang.io/:
 
 import std.stdio;
 void main()
 {
    ushort first = 5;
    ushort second = 1000;

    ushort result = first + second;

    writeln(result);
 }
I hae this error:
 onlineapp.d(7): Error: cannot implicitly convert expression 
 cast(int)first + cast(int)second of type int to ushort
Why they are "int" when I declared them as "ushort"??? ushort + ushort = ushort, not int. In C++ there aren't any such issues...
It's called integer promotion and it originates from C. And yes C++ does have such support in some variant (I really don't feel like comparing the two).
Aug 20 2018
parent reply Andrey <saasecondbox yandex.ru> writes:
On Monday, 20 August 2018 at 08:42:20 UTC, rikki cattermole wrote:
 It's called integer promotion and it originates from C.
 And yes C++ does have such support in some variant (I really 
 don't feel like comparing the two).
And I should do? Always use "cast" operator when I operate not with ints?
Aug 20 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 20/08/2018 8:48 PM, Andrey wrote:
 On Monday, 20 August 2018 at 08:42:20 UTC, rikki cattermole wrote:
 It's called integer promotion and it originates from C.
 And yes C++ does have such support in some variant (I really don't 
 feel like comparing the two).
And I should do? Always use "cast" operator when I operate not with ints?
Yes. On x86 int's will be faster just an FYI so it does make sense to use them for computation.
Aug 20 2018
parent reply Andrey <saasecondbox yandex.ru> writes:
On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote:
 Yes. On x86 int's will be faster just an FYI so it does make 
 sense to use them for computation.
Inconveniently always use casts. Why in D one decided to do in such way?
Aug 20 2018
next sibling parent rikki cattermole <rikki cattermole.co.nz> writes:
On 20/08/2018 9:19 PM, Andrey wrote:
 On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote:
 Yes. On x86 int's will be faster just an FYI so it does make sense to 
 use them for computation.
Inconveniently always use casts. Why in D one decided to do in such way?
C.
Aug 20 2018
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, August 20, 2018 3:19:04 AM MDT Andrey via Digitalmars-d-learn 
wrote:
 On Monday, 20 August 2018 at 08:49:00 UTC, rikki cattermole wrote:
 Yes. On x86 int's will be faster just an FYI so it does make
 sense to use them for computation.
Inconveniently always use casts. Why in D one decided to do in such way?
It's a combination of keeping the C semantics (in general, C code is valid D code with the same semantics, or it won't compile) and the fact that D requires casts for narrowing conversions. When you add two shorts in C/C++, it converts them to int just like D does. It's just that C/C++ has implicit narrowing casts, so if you assign the result to a short, it then converts the result to short even if that means that the value could be truncated, whereas D requires that you explicitly cast to convert to int rather than silently truncating. It does prevent certain classes of problems (e.g. there are plenty of bugs in C/C++ due to implicit narrowing conversions), but it can also get pretty annoying if you're doing much math on integer types smaller than int, and you either know that they aren't going to overflow or truncate, or you don't care that they will. But if you're only doing math on such small integeral types occasionally, then it pretty much just means that once in a while, you get briefly annoyed when you forget to add a cast, and the compiler yells at you. - Jonathan M Davis
Aug 20 2018
parent reply Andrey <saasecondbox yandex.ru> writes:
On Monday, 20 August 2018 at 09:56:13 UTC, Jonathan M Davis wrote:
 It's a combination of keeping the C semantics (in general, C 
 code is valid D code with the same semantics, or it won't 
 compile) and the fact that D requires casts for narrowing 
 conversions. When you add two shorts in C/C++, it converts them 
 to int just like D does. It's just that C/C++ has implicit 
 narrowing casts, so if you assign the result to a short, it 
 then converts the result to short even if that means that the 
 value could be truncated, whereas D requires that you 
 explicitly cast to convert to int rather than silently 
 truncating.

 It does prevent certain classes of problems (e.g. there are 
 plenty of bugs in C/C++ due to implicit narrowing conversions), 
 but it can also get pretty annoying if you're doing much math 
 on integer types smaller than int, and you either know that 
 they aren't going to overflow or truncate, or you don't care 
 that they will. But if you're only doing math on such small 
 integeral types occasionally, then it pretty much just means 
 that once in a while, you get briefly annoyed when you forget 
 to add a cast, and the compiler yells at you.

 - Jonathan M Davis
Understood. Is there a workaround to reduce amount of manual casts of input types T into output T? May be one can write some module-global operator "plus", "minus"..? Like in C++:
 template<typename T>
 T operator+(T first, T second)
{
    return static_cast<T>(first + second);
}
Aug 20 2018
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Monday, August 20, 2018 4:29:56 AM MDT Andrey via Digitalmars-d-learn 
wrote:
 On Monday, 20 August 2018 at 09:56:13 UTC, Jonathan M Davis wrote:
 It's a combination of keeping the C semantics (in general, C
 code is valid D code with the same semantics, or it won't
 compile) and the fact that D requires casts for narrowing
 conversions. When you add two shorts in C/C++, it converts them
 to int just like D does. It's just that C/C++ has implicit
 narrowing casts, so if you assign the result to a short, it
 then converts the result to short even if that means that the
 value could be truncated, whereas D requires that you
 explicitly cast to convert to int rather than silently
 truncating.

 It does prevent certain classes of problems (e.g. there are
 plenty of bugs in C/C++ due to implicit narrowing conversions),
 but it can also get pretty annoying if you're doing much math
 on integer types smaller than int, and you either know that
 they aren't going to overflow or truncate, or you don't care
 that they will. But if you're only doing math on such small
 integeral types occasionally, then it pretty much just means
 that once in a while, you get briefly annoyed when you forget
 to add a cast, and the compiler yells at you.

 - Jonathan M Davis
Understood. Is there a workaround to reduce amount of manual casts of input types T into output T? May be one can write some module-global operator "plus", "minus"..? Like in C++:
 template<typename T>
 T operator+(T first, T second)

{

    return static_cast<T>(first + second);

}
D only allows overloaded operators to be declared on types, so you can't overload any operators for any built-in types (or any types that you don't control the declaration of for that matter). You could create a wrapper function and use that instead of +. You could even make it use string mixins like opBinary does if you wanted to - e.g. something like short doOp(string op)(short lhs, short rhs) if(op == "+" || op == "-" || op == "*" || op == "/" || op == "%") { mixin("return cast(short)(lhs " ~ op ~ " rhs);"); } val1 = val1.doOp!"+"(val2); but you're not going to be able to get something like val1 = val1 + val2; to work with just short. Alternatively, you could create a wrapper type and use that instead of using short directly. IIRC, the last time that someone was complaining in the main newsgroup about all of the required casts, someone posted a link to something that did that. If the casts are too annoying for you, that would probably be the best solution. - Jonathan M Davis
Aug 20 2018
prev sibling parent Jim Balter <Jim Balter.name> writes:
On Monday, 20 August 2018 at 08:34:56 UTC, Andrey wrote:
 Hello,
 Here is a code that you can execute using online compiler 
 https://run.dlang.io/:

import std.stdio;
void main()
{
    ushort first = 5;
    ushort second = 1000;
 
    ushort result = first + second;
 
    writeln(result);
}
I hae this error:
 onlineapp.d(7): Error: cannot implicitly convert expression 
 cast(int)first + cast(int)second of type int to ushort
Why they are "int" when I declared them as "ushort"??? ushort + ushort = ushort, not int. In C++ there aren't any such issues...
Only if you make the mistake of compiling without warnings. Otherwise, the C++ compiler will warn that you're converting an int to a ushort.
Aug 21 2018