c++data-race

In C++, does a data race in one possible scenario render the program's behaviour undefined even if that scenario never gets executed?


The following program contains a data race:

#include <iostream>
#include <thread>
#include <chrono>
#include <string>

using namespace std::chrono_literals;

int sharedVar = 42;

void func(const std::string& threadName) {
    int input;

    while(true) {
        std::cout<<"["<<threadName<<"]Enter a number: "<<std::endl;
        std::cin>>input;

        if(input == 42) {
            sharedVar++;
        }
        else {
            std::this_thread::sleep_for(1s);
        }
    }
}


int main() {

    std::thread t(func, "thread");
    t.detach();

    func("main");
}

Both threads are accessing sharedVar without any synchronisation if they are given input == 42 from the user.

As per cppreference,

If a data race occurs, the behavior of the program is undefined.

Is the above program guaranteed to work fine (without any undefined behaviour) if input == 42 is never provided?

or

Does the scenario of execution (whether 42 is provided in the input or not at runtime) not matter at all and the program is always undefined.

I ask this question because sometimes, during the discussion on data races, the discussion goes into the details of execution; e.g. in the above case whether the user will provide 42 or not in the input.

Edit Just wanted to add this article I found online which seemed relevant. As per my understanding of this, the input which is given does not matter. The behaviour will remain undefined.

Edit 2 Basically the type 2 functions mentioned here is what I'm interested in.


Solution

  • The following program contains a data race

    For some input values, particularly both threads need to see input of 42, not just one thread.

    A data race is a property of an execution, not of the program in the abstract. From [intro.races#21]:

    The execution of a program contains a data race if

    If yes, then is the above program guaranteed to work fine (without any undefined behaviour) if input == 42 is never provided?

    Yes. It will continue to loop forever prompting for and accepting input.

    Aside: I would be wary of supplying functions with reference parameters to std::thread::thread, although in this case it is fine, because you pass a const char[] not a rvalue std::string.