Schrodinger's CTFE
Steven Schveighoffer
schveiguy at gmail.com
Wed Jul 15 20:33:23 UTC 2020
I found a weird workaround to the "Unreachable code" problem.
In a nutshell, code that is sometimes reachable given the correct
template parameters can be flagged as unreachable when instantiated with
different ones.
An example (compile with -w):
int foo(bool x)()
{
if(x) return 1;
return 2;
}
void main()
{
auto x = foo!false(); // ok
auto y = foo!true(); // Warning: "return 2;" is unreachable
}
A weird solution is to declare a boolean value somewhere as always true,
and use it to "break" free from the constant folding:
int foo(bool x)()
{
auto b = true;
if(x && b) return 1;
return 2;
}
The boolean will likely be removed by the optimizer, but it's kind of a
clunky solution.
However, we also have a special boolean __ctfe that is treated as a
runtime variable for things like checking reachability, but treated as a
compile-time constant for code generation (so truly unreachable code is
simply removed instead of being flagged for unreachability).
This also works, but is only good for compile time or runtime (depending
on your intentions for foo):
int foo(bool x)()
{
if(x && __ctfe) return 1; // or !__ctfe for runtime
return 2;
}
I was going to ask if we could have another special variable that is
like __ctfe in these respects, but is *always* true for both runtime and
compile time, but I actually found out a weird trick. This works, and
does the same thing at both runtime and compile time, plus will only
generate one branch for the runtime (without even the optimizer turned on):
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?
-Steve
More information about the Digitalmars-d
mailing list