Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 30, 2013 unnecessary casts | ||||
---|---|---|---|---|
| ||||
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. |
January 30, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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
|
January 30, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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.
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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.)
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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.
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Thanks. It's not that I'm worried about, I was only curious. :) |
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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?
|
January 31, 2013 Re: unnecessary casts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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 |
Copyright © 1999-2021 by the D Language Foundation