1

Example

int a = 8;
if(a < 9){
 something1();
}
else{
 something2();
}

what will happen if there was a context switch right before the if statment (after the init of a) which will change a to a=11, and then return to the above code, and before getting to else, another context switch which will change a to a= 8, and again return to the above code. will it still be in the else statment?

thanks

  • 1
    It should skip the else unless you return to the if again. Because else is only entered when if is not true. – IndieGameDev Jul 13 '20 at 11:44
  • You'd need to make `a` `volatile`, or the compiler would replace everything with `something1();` – Andreas is moving to Codidact Jul 13 '20 at 12:16
  • @Andreas -- `volatile` is never the right answer to multi-threading issues. If `a` is shared between threads, the right answer is to make it `std::atomic a = 8;`. – Pete Becker Jul 13 '20 at 12:42
  • @PeteBecker [Ok](https://stackoverflow.com/questions/2484980/why-is-volatile-not-considered-useful-in-multithreaded-c-or-c-programming), but it would still prevent the compiler from optimizing away the necessary operations in the OP's example. – Andreas is moving to Codidact Jul 13 '20 at 12:46
  • @Andreas -- the behavior of the code in the question is undefined. Marking `a` as `volatile` doesn't change that. – Pete Becker Jul 13 '20 at 12:49

2 Answers2

0

if-statements are usually implemented with conditional jumps in assembly code. But they don't have to be. E.g take this code for example:

int main(int argc, char** argv) {
    if (argc > 42)
        return 62;
    else
        return 31;
}

which clang compiles as (with optimization):

main: # @main
  cmp edi, 42
  mov ecx, 62
  mov eax, 31
  cmovg eax, ecx
  ret

Anyways you will usually have a single compare somewhere, i.e the variable is only checked once. In this case the variable is checked at the cmp edi, 42 statement.

In general the behaviour is simply undefined.

Sebastian Hoffmann
  • 2,815
  • 1
  • 12
  • 22
  • @Sebasitan Hoffmann, thanks, but genrally can it ignore both the if and else in some undefined situation (or it must enter at least on of the statement)? – johnTheSo99 Jul 13 '20 at 11:49
  • @johnTheSo99 it's impossible to reason about undefined behaviour in a general fashion. Usually it should'nt be possible but that doesn't mean it could never happen. If you have concrete code you can always check the resulting assembly. – Sebastian Hoffmann Jul 13 '20 at 11:50
  • @johnTheSo99 It is e.g very likely that you don't even see any change in the variable (unless declared `volatile`) because it is stored inside some register (like in this case) – Sebastian Hoffmann Jul 13 '20 at 11:52
  • @Sebasitan Hoffmann, in the example that you showned, is it possible to not get into both the if and else statement? – johnTheSo99 Jul 13 '20 at 11:53
  • @johnTheSo99 No it isn't in this particular example. Have you read the answer? – Sebastian Hoffmann Jul 13 '20 at 11:54
  • @Sebasitan Hoffmann, yes, but I wanted to make sure that I understand it correctly, thanks. – johnTheSo99 Jul 13 '20 at 11:56
0

If a can be modified by some other thread then the code must synchronize the two threads somehow. The simplest way, which seems appropriate here, is to make a atomic:

std::atomic<int> a = 8;

Now multiple threads can read and write the value of a with well-defined behavior. The actual value the you see depends on the order of the reads and writes, of course, and the language definition can't help you with that. But making a atomic ensures that every read will see a value that was actually written, and that the compiler won't optimize out the test in the if statement.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165