Schrodinger's CTFE

Steven Schveighoffer schveiguy at gmail.com
Wed Jul 15 22:58:53 UTC 2020


On 7/15/20 6:44 PM, Andrei Alexandrescu wrote:
> On 7/15/20 4:33 PM, Steven Schveighoffer wrote:
>>
>> int foo(bool x)()
>> {
>>     if(x && (__ctfe || !__ctfe)) return 1;
>>     return 2;
>> }
>>
>> I think this is a way to fix some of those static foreach loops with 
>> returns which can have these reachability problems. Only, it's really 
>> verbose and ugly. Maybe we still should have that other variable?
> 
> Would a function work?
> 
> @property
> bool __schro() pure nothrow @nogc { return __ctfe || !__ctfe; }
> 

I actually tried that, and it does prevent the "Unreachable statement" 
problem, but the runtime code contains a call to that function where it 
is used, which means that it's not as effective in all cases.

With a straight usage of the expression, you get (without -inline or -O):

pure nothrow @nogc @safe int onlineapp.foo!(false).foo():
		push	RBP
		mov	RBP,RSP
		mov	EAX,2
		pop	RBP
		ret
		add	[RAX],AL

pure nothrow @nogc @safe int onlineapp.foo!(true).foo():
		push	RBP
		mov	RBP,RSP
		mov	EAX,1
		pop	RBP
		ret
		add	[RAX],AL

With the schro function, you get the same result for foo!false (as the 
short circuiting of the if statement prunes out the check of __ctfe), 
but you get this for foo!true:

pure nothrow @nogc int onlineapp.foo!(true).foo():
		push	RBP
		mov	RBP,RSP
		call	  pure nothrow @property @nogc bool onlineapp.schro()@PLT32
		test	AL,AL
		je	L14
		mov	EAX,1
		pop	RBP
		ret
L14:		mov	EAX,2
		pop	RBP
		ret
		add	[RAX],AL

With -inline, it results as the same thing.

Note that if you put it in a function, you can just return true, you 
don't need the __ctfe || !__ctfe.

-Steve


More information about the Digitalmars-d mailing list