Fixing the issue with "Statement unreachable"

Steven Schveighoffer schveiguy at gmail.com
Thu Apr 30 19:21:23 UTC 2020


On 4/30/20 2:25 PM, matheus wrote:
> On Thursday, 30 April 2020 at 14:29:27 UTC, Steven Schveighoffer wrote:
>> On 4/30/20 10:02 AM, matheus wrote:
>>> ...
>>> // WHILE BELOW GIVES THE ERROR: https://d.godbolt.org/z/8rNdjJ
>>> import std.stdio;
>>> bool test(){
>>>      static if(cond){
>>>          return true;
>>>      }
>>>      return false;
>>> }
>>>
>>> enum bool cond = true;
>>> bool func();
>>>
>>> void main(string[ ] args) {
>>>      writeln(test());
>>> }
>>>
>>> As you can see, when you explicitly define a return inside a static 
>>> if, the compiler emits the warning.
>>
>> Right, the first would still include the return false as generated 
>> code, this is not in dispute. And in fact, in your case, I would say 
>> the error is legitimate (that line is not reachable).
> 
> Yes I got what you mean, and I would agree with that logic too, except 
> that while this gives a warning:
> 
> bool test(){
>      static if(cond){
>          return true;
>      }
>      return false;
> }
> 
> Just adding "else" to the code above will make it work normally:
> 
> bool test(){
>      static if(cond){
>          return true;
>      }else
>          return false;
> }
> 
> This is a bit weird for me, I really thought the compiler would be smart 
> enough to handle this.

So what is happening is that the static if is literally including or 
trimming out the code based on the boolean.

It's as if you wrote:

bool test() {
    // static if(cond) { => included for cond == true
       return true;
    // }
    return false;
}

which the "linter" or whatever generates the warning looks at and says 
it's no good, because it looks like 2 sequential return statements.

What it really should do is simply remove the second return and shut up ;)

> 
> If I was doing a benchmark between functions I'd like to do:
> 
> void func(){
>      static if(TryDoSomethingA){
>          doSomethingA();
>          return;
>      }
>      doSomethingB();
> }
> 
> But to make this work I'll need to add an extra "else", which I hate and 
> I always try to avoid in my code.

There is one possibility, which is only valid for static conditionals:

void func() {
    static if(cond)
      return;
    else: // note the colon
    return; // note the indentation
}

Basically, it's saying, do everything else in this scope, but don't make 
me indent. It could be a simple way to fix the problem. I think Andrei 
suggested this in the bug report quoted before. Essentially, the 
compiler could insert an else: whenever it encounters a static if 
without an else, where all paths exit the outer scope for that compilation.

But the compiler should be smart enough to just not report errors in 
these cases.

> 
> Well my background is C and maybe there is a reason for the use of 
> "else" with "static if".

Yes, if you consider the AST rewriting that static if does, it makes 
sense, because the linter doesn't know how the AST came about.

-Steve


More information about the Digitalmars-d mailing list