5

I've read already a couple times (e.g. here Compiler: What if condition is always true / false) that any decent c++ compiler will opt-out something like

if(false)
{
 ...
}

But what if there is an intentional jump into this if(false) block. I'm having something like this in mind

#include <iostream>

void func(int part){
    switch (part) {
    case 0:{
        if(false)
            case 1:{std::cout << "hello" << std::endl;}
        break;
    }
    default:
        break;
    }
}

int main()
{
    func(0);
    func(1);
    return 0;
}

Is any decent c++ compiler going to respect the jump or will there eventually going to be some problems with opting-out?

jxh
  • 69,070
  • 8
  • 110
  • 193
ezegoing
  • 526
  • 1
  • 4
  • 18
  • 1
    Does that even compile? – Robert Harvey Oct 30 '19 at 18:26
  • Compiles ok https://godbolt.org/z/8VZw1w and I think it ok from a standards perspective – Richard Critten Oct 30 '19 at 18:27
  • gcc 7.4.0 no problem :) – ezegoing Oct 30 '19 at 18:28
  • 1
    The compilers job is to generate the code with proper side effects. Why would a c++ compiler not going to "respect" (what does that mean?) the "jump"? What "problems with opting-out" do you see? Do you ask if the function can be optimized to `if (part == 1) std::cout << .... ;` ? – KamilCuk Oct 30 '19 at 18:28
  • Yeah, this is something that you probably shouldn't do at all. Find a better way to do whatever it is that you're trying to do. – Robert Harvey Oct 30 '19 at 18:29
  • Keep in mind that compilers are allowed to optimize anything as long as the effect is still the same. So if this isn't breaking any rules (UB, ill-formed, syntax errors, etc), then the compiler has to honor it . But again, that's only if you're not breaking rules. –  Oct 30 '19 at 18:31
  • @KamilCuk First I was concerned - like others here - if that is even going to compile for all compilers. Then I was thinking how much of OPT flags could play a role, something like could -O3 cause problems here... – ezegoing Oct 30 '19 at 18:33
  • @Chipster So am I breaking any rules here? – ezegoing Oct 30 '19 at 18:34
  • 3
    if you have such code in your code base, compiler bugs are the least of your problems – Jeffrey Oct 30 '19 at 18:35
  • This should be illegal, IMHO. – 500 - Internal Server Error Oct 30 '19 at 18:38
  • @Jeffrey fair enough. I'm deferring functions and this is what it ended up to be. I also dont know how much different it could look... – ezegoing Oct 30 '19 at 18:38
  • @ezegoing No you are not breaking any rules. This will print `hello` once through the `func(1)` call and that can't be changed by the compiler. – walnut Oct 30 '19 at 18:41
  • `case 0:{ case 1: }` definitely feels like is should be breaking rules because you are jumping into the middle of a block. Although the ancient now out of favor `goto` could do things like this I think, so maybe not. –  Oct 30 '19 at 18:42
  • 3
    @Chipster `switch` is a `goto` table. It uses labels exactly like a `goto` does. And it has the same rules about skipping declarations as `goto`. It's no surprise it behaves exactly like a `goto`. Edit : This is why it's able to produce the example used in this question. – François Andrieux Oct 30 '19 at 18:43
  • @jxh, my question is really bout the if(false) jump and not the jump itself, should have chosen a silly goto then. I don't care about the duffs toy, this stuff is being used by my colleagues frequently. So i dont see a duplicate to this linked thread :S – ezegoing Oct 30 '19 at 18:49
  • @ezegoing [edit your question](https://stackoverflow.com/posts/58631602/edit) and add that information in. –  Oct 30 '19 at 18:51
  • @ezegoing: The compiler can perform dead code elimination if the code is dead. The code after `case 1:` isn't dead. The reason it isn't dead is because your code is Duff's Device. QED. – jxh Oct 30 '19 at 18:52
  • @Chipster well that is the question title *Is there any problem in jumping into if(false) block? [duplicate] * lol and the whole question... – ezegoing Oct 30 '19 at 18:53
  • @ezegoing Yes, but since it's now been confused as a duplicate, it's a good idea to add a statement why it's not a duplicate in the question. –  Oct 30 '19 at 18:54
  • If your question is really about "jumping", you can rewrite your example with a `goto` instead. But, the crux of the answer is the same: if the code is reachable via a jump, then it is not dead code, and so the compiler will not apply DCE. – jxh Oct 30 '19 at 19:00
  • I do want to stress: The question was well composed and straightforward to understand. I am just saying if you recognized the `switch` into `if` construction as Duff's Device, you would have known the code would not be subject to being optimized out. Upvote for the question! – jxh Oct 30 '19 at 19:10

1 Answers1

8

The code doesn't appear to be Undefined Behavior. Therefore any optimizations are not allowed to produce any effects which would affect the behavior of the code.

Note: Related to this kind of code, one thing you are not allowed to do is "goto" over definitions of local variables. But this code doesn't do that, so no problem.

Another note: If you have this kind of code in a "real" (not toy, experiment, obfuscation exercise etc) program, you should really refactor it into something which doesn't elicit quite so many WTFs from anybody reading the code.

hyde
  • 60,639
  • 21
  • 115
  • 176
  • 1
    The technique is a well-known one, so it should be idiomatic in the code bases that use it. If it isn't used in a code base, then it may be best not to introduce it. – jxh Oct 30 '19 at 18:40
  • 2
    @jxh Interesting. In fact now that I think of it, I could have had a use case for exactly this a week or two ago... except it wouldn't ever fly in code review :-D – hyde Oct 30 '19 at 18:45
  • 1
    @hyde dont forget to cite me XD – ezegoing Oct 30 '19 at 18:56