www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - static if else behavior and is type comparison

reply Fynn =?UTF-8?B?U2NocsO2ZGVy?= <fynnos live.com> writes:
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?
Mar 11 2016
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Mar 11 2016
next sibling parent Fynn =?UTF-8?B?U2NocsO2ZGVy?= <fynnos live.com> writes:
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 :)
Mar 11 2016
prev sibling next sibling parent reply Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
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
Mar 11 2016
parent Marc =?UTF-8?B?U2Now7x0eg==?= <schuetzm gmx.net> writes:
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 ';'
Mar 11 2016
prev sibling parent Chris Wright <dhasenan gmail.com> writes:
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.
Mar 11 2016
prev sibling parent Andrea Fontana <nospam example.com> writes:
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 { ... }
Mar 11 2016