Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
March 11, 2016 static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Hi all, I'm currently working on a small utility to control the EC (embedded controller) of my notebook. I need to call an external C library and choose different methods based on the desired return type. I came up with a solution based on type checking and static if - however I ran into a weird issue: void main() { pragma(msg, "only ubytes:"); ubyte x = typeBasedDispatcher!ubyte(); pragma(msg, "only ushorts:"); ushort y = typeBasedDispatcher!ushort(); pragma(msg, "only uints:"); uint z = typeBasedDispatcher!uint(); } U typeBasedDispatcher(U)() if (is(U == ubyte) || is(U == ushort) || is(U == uint)) { static if (is(U == ubyte)) { pragma(msg, "is ubyte"); return fnUbyte(); } else if (is(U == ushort)) { pragma(msg, "is ushort"); return fnUshort(); } else if (is(U == uint)) { pragma(msg, "is unit"); return fnUint(); } else { pragma(msg, "ERROR!? should not reach this in any case!?"); } } ubyte fnUbyte() { return ubyte.init; } ushort fnUshort() { return ushort.init; } uint fnUint() { return uint.init; } Output of dmd 2.070.0 on Windows: only ubytes: is ubyte only ushorts: is ushort is unit ERROR! should not reach this in any case! staticIfElse.d(22): Error: cannot implicitly convert expression (fnUint()) of type uint to ushort staticIfElse.d(7): Error: template instance staticIfElse.typeBasedDispatcher!ushort error instantiating only uints: is ushort is unit ERROR! should not reach this in any case! Am I doing anything wrong here or is this a bug? |
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fynn Schröder | You've been bitten by a common usability issue. :) On 03/11/2016 12:02 AM, Fynn Schröder wrote: > static if (is(U == ubyte)) { > pragma(msg, "is ubyte"); > return fnUbyte(); > } else if (is(U == ushort)) { You mean 'else static if'. (Not your fault: I (and others) wish the compiler warned about this problem.) Ali |
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Fynn Schröder | On Friday, 11 March 2016 at 08:02:41 UTC, Fynn Schröder wrote:
> Am I doing anything wrong here or is this a bug?
You should write:
static if { ... }
else static if { ... }
else static if { ... }
|
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Friday, 11 March 2016 at 08:21:33 UTC, Ali Çehreli wrote:
> You mean 'else static if'. (Not your fault: I (and others) wish the compiler warned about this problem.)
Thanks! Such an easy mistake..
You're right Ali, it would be nice if the compiler gave a warning :)
|
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On 03/11/16 09:21, Ali Çehreli via Digitalmars-d-learn wrote: > You've been bitten by a common usability issue. :) > > On 03/11/2016 12:02 AM, Fynn Schröder wrote: >> static if (is(U == ubyte)) { >> } else if (is(U == ushort)) { > > You mean 'else static if'. (Not your fault: I (and others) wish the compiler warned about this problem.) It can not warn about this "problem" - because it's a perfectly fine and relatively common construct (a RT check guarded by a CT check). The problem comes from the static-if pseudo-keyword hack -- "static if" is effectively a keyword; if the syntax was eg "#if" then such mistakes would be less likely. Obviously, it's a bit late for such language change. One thing that the compiler could warn about is: a RT-if that depends only on the result of an is-expression; that would have caught the case above and rarely be wrong (with an easy way to make the compiler happy). It would still miss more complex cases, but those can't be warned about as they can occur legitimately in generic code. artur |
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Artur Skawina | On Friday, 11 March 2016 at 12:10:53 UTC, Artur Skawina wrote:
> On 03/11/16 09:21, Ali Çehreli via Digitalmars-d-learn wrote:
>> You've been bitten by a common usability issue. :)
>>
>> On 03/11/2016 12:02 AM, Fynn Schröder wrote:
>>> static if (is(U == ubyte)) {
>
>>> } else if (is(U == ushort)) {
>>
>> You mean 'else static if'. (Not your fault: I (and others) wish the compiler warned about this problem.)
>
> It can not warn about this "problem" - because it's a perfectly
> fine and relatively common construct (a RT check guarded by a CT
> check).
It can first deprecate and later disallow
static if(...) ... else if(...) ...
It's always possible (and IMO preferable) to write the clearer
static if(...) { ... } else { if(...) ... }
It already does this for similar error-prone cases, e.g.
if(...) ;
while(...) ;
// Error: use '{ }' for an empty statement, not a ';'
|
March 11, 2016 Re: static if else behavior and is type comparison | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Fri, 11 Mar 2016 00:21:33 -0800, Ali Çehreli wrote: > You've been bitten by a common usability issue. :) > > On 03/11/2016 12:02 AM, Fynn Schröder wrote: > > static if (is(U == ubyte)) { > > pragma(msg, "is ubyte"); > > return fnUbyte(); > > } else if (is(U == ushort)) { > > You mean 'else static if'. (Not your fault: I (and others) wish the > compiler warned about this problem.) > > Ali https://github.com/Hackerpilot/Dscanner/pull/309 Turns out it's much faster to change a lint tool than to change the compiler. |
Copyright © 1999-2021 by the D Language Foundation