1

I'm testing the possibilities of if constexpr and I was wondering if it was possible to remove control flow statements with it.

The code I'm testing is:

int main() {
    void *indirect_label;
    if constexpr (false) {
       goto label; // Rejected by MSVC, clang and GCC
    }
    if constexpr (false) {
        continue;  // Rejected by clang and GCC
    }
    if constexpr (false) {
        break; // Rejected by clang and GCC
    }
    if constexpr (false) {
        goto *indirect_label; // Rejected by clang and MSVC
    }
    return 1;
}

I added a test for the indirect gotos language extension implemented by GCC and clang.

Considering that if constexpr should discard the statements if the condition is false, why does MSVC and GCC accept some parts of the code (but different) and clang rejects all four.

What behaviour is correct?

  • 1
    Sitting back and waiting for someone to completely miss the point of the question and start freaking out over the `goto`s. – user4581301 Feb 21 '20 at 18:16
  • 5
    Do note that `if constexpr` is meant to be used with templates. If the code is not dependent then body is still compiled: https://stackoverflow.com/questions/59393908/if-constexpr-why-is-discarded-statement-fully-checked – NathanOliver Feb 21 '20 at 18:17
  • Where is `label` defined? And can you [edit] into the question a sample of the error messages you get from the compilers? – 1201ProgramAlarm Feb 21 '20 at 18:19
  • 2
    None of these control statements make sense in the context in which they are used. You cannot use `continue;` or `break;` at these points and `label` does not exist. Indirect gotos are not standard C++. – walnut Feb 21 '20 at 18:19
  • I was wondering if `if constexpr` could remove them. I am using this to implement a few macros. – Nicolas Bértolo Feb 21 '20 at 18:20
  • 1
    If you could show us what you are trying to achieve, we might be able to help you out with that. – NathanOliver Feb 21 '20 at 18:22
  • @NathanOliver: What he's trying to achieve is obvious: he wants to use `if constexpr` to eliminate code. Why is kind of irrelevant; he's asking about the powers of `if constexpr`. – Nicol Bolas Feb 21 '20 at 18:25
  • I'm trying to "forward" control flow from a function to another. Imagine returning an object of type `cf` and then a macro using `if constexpr` to issue a `break` statement. – Nicolas Bértolo Feb 21 '20 at 18:25
  • 1
    @NicolasBértolo: That's not even *close* to a power of `if constexpr`. Functions are isolated from each other, and `if constexpr` changes nothing about it. – Nicol Bolas Feb 21 '20 at 18:25
  • Of course. It seems I did not explain myself correctly. If `if constexpr` cannot do this then I will have to implement it using many more macros than I'd like, one for each combination of control flow statements possible. – Nicolas Bértolo Feb 21 '20 at 18:28

1 Answers1

4

if constexpr is not a macro. Indeed, it only gains powers distinct from a regular if statement in the specific circumstances of both being in a template and the condition itself being based on template parameters. And even then, the discarded statements have to be at least potentially legitimate.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • What exactly should be understood by "*potentially legitimate*"? – Fureeish Feb 21 '20 at 18:25
  • 1
    @Fureeish: The rules for discarded statements are extremely complicated and probably best dealt with in a separate question. The gist of it is basically "ignore the question of whether a template could be instantiated with those argument; if all of them work out, is it still legit C++?" `goto label_that_doesnt_exist` is most definitely never going to be legitimate C++. Same goes for `continue` or `break` in a place where those aren't allowed. – Nicol Bolas Feb 21 '20 at 18:26
  • So is it a bug in MSVC that it accepts `break` and `continue` outside a loop? – Nicolas Bértolo Feb 21 '20 at 18:29
  • 1
    Also, `break;` statements are valid only inside loops and `switch` statements. `continue;` statements are valid only inside loops. – R Sahu Feb 21 '20 at 18:31