www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - unnecessary casts

reply "Namespace" <rswhite4 googlemail.com> writes:
Is the compiler (dmd) fit enough to detect and avoid unnecessary 
casts?

E.g.
[code]
void foo(T)(T num) {
     int f = cast(int) num;
     // ...
}

foo(42); // cast is unnecessary
foo(4.2); // cast is necessary
[/code]

Or should I wrote everytime

[code]
void foo(T)(T num) {
static if (is(T == int) || isImplicitlyConvertible!(T, int)) {
     int f = num;
} else {
     int f = cast(int) num;
}
     // ...
}
[/code]

Until now I count on the compiler, that it detect this cases and 
avoid casts. But I'm not 100% sure, so I want to ask.
Jan 30 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
On Wednesday, 30 January 2013 at 22:49:01 UTC, Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid 
 unnecessary casts?
I think the most important casts most worth avoiding are the ones you write in the code (because they are a source of bugs), not the ones the compiler performs :-) Bye, bearophile
Jan 30 2013
parent reply "Namespace" <rswhite4 googlemail.com> writes:
On Wednesday, 30 January 2013 at 22:57:39 UTC, bearophile wrote:
 On Wednesday, 30 January 2013 at 22:49:01 UTC, Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid 
 unnecessary casts?
I think the most important casts most worth avoiding are the ones you write in the code (because they are a source of bugs), not the ones the compiler performs :-) Bye, bearophile
I'm talking about exactly these kind of casts. See my example.
Jan 30 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Namespace:

 I'm talking about exactly these kind of casts. See my example.
I don't understand what you are trying to minimize. In both versions of your foo function you have 1 cast, so you aren't minimizing the number of casts you are writing in the code. Bye, bearophile
Jan 30 2013
prev sibling next sibling parent reply "Jonathan M Davis" <jmdavisProg gmx.com> writes:
On Wednesday, January 30, 2013 23:49:00 Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid unnecessary
 casts?
 
 E.g.
 [code]
 void foo(T)(T num) {
 int f = cast(int) num;
 // ...
 }
 
 foo(42); // cast is unnecessary
 foo(4.2); // cast is necessary
 [/code]
 
 Or should I wrote everytime
 
 [code]
 void foo(T)(T num) {
 static if (is(T == int) || isImplicitlyConvertible!(T, int)) {
 int f = num;
 } else {
 int f = cast(int) num;
 }
 // ...
 }
 [/code]
 
 Until now I count on the compiler, that it detect this cases and
 avoid casts. But I'm not 100% sure, so I want to ask.
You'd have to look at the generated code to know for sure what it did, but it would be poor optimization to not strip the cast when casting from a value to its own type. And really, I'd argue that it's premature optimization to really worry about it in the first place. I'd argue that it's a bug if unnecessary casts are not optimized out, but unless you're searching for compiler bugs, there shouldn't be any reason to worry about it. - Jonathan M Davis
Jan 30 2013
parent "Namespace" <rswhite4 googlemail.com> writes:
Thanks. It's not that I'm worried about, I was only curious. :)
Jan 31 2013
prev sibling next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 01/30/2013 11:49 PM, Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid unnecessary casts?
 ...
Well, 'unnecessary casts' are a no-op anyway. (Yes, afaik DMD will even eliminate them from the AST.)
Jan 30 2013
parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Thursday, 31 January 2013 at 00:03:43 UTC, Timon Gehr wrote:
 On 01/30/2013 11:49 PM, Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid 
 unnecessary casts?
 ...
Well, 'unnecessary casts' are a no-op anyway. (Yes, afaik DMD will even eliminate them from the AST.)
There is a bug though that the value returned by an opCast should be an r-value. However, because the cast is transformed into a no-op, then it becomes erroneously legal to take the address of the cast value, or to pass it by ref: //---- void foo()(auto ref int i) {++i;} void main() { double d = 0; int i = 0; foo(cast(int)d); //OK: Calls foo(int); foo(cast(int)i); //Oops! Calls foo(ref int); assert(d == 0); //OK assert(i == 0); //Darn... } //---- I *think* this is a known bug. I couldn't find the entry though... Can anybody confirm?
Jan 31 2013
prev sibling next sibling parent n00b <n00b nospam.com> writes:
Le 30/01/2013 17:49, Namespace a écrit :
 Is the compiler (dmd) fit enough to detect and avoid unnecessary casts?

 E.g.
 [code]
 void foo(T)(T num) {
 int f = cast(int) num;
 // ...
 }

 foo(42); // cast is unnecessary
 foo(4.2); // cast is necessary
 [/code]

 Or should I wrote everytime

 [code]
 void foo(T)(T num) {
 static if (is(T == int) || isImplicitlyConvertible!(T, int)) {
 int f = num;
 } else {
 int f = cast(int) num;
 }
 // ...
 }
 [/code]

 Until now I count on the compiler, that it detect this cases and avoid
 casts. But I'm not 100% sure, so I want to ask.
When the template gets instantiated, the compiler has to determine what "cast(int)" exactly means for type T ; if T is int, the obvious answer is to do nothing, so I don't see a problem. Just my guess.
Jan 30 2013
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 01/30/2013 02:49 PM, Namespace wrote:
 Is the compiler (dmd) fit enough to detect and avoid unnecessary casts?
Also consider std.conv.to. The many speciliazions of toImpl() that it calls should do the safe and efficient thing. Ali
Jan 31 2013