1

I'm in the design phase of a multi threading problem I might implement in c++. Will be the first time implementing something multi threaded in c++. The question is quite simple: If I have a function with a const parameter as input, is it just the function under consideration that is not allowed to alter it? Or does c++ guarantee that the parameter will not change (even if another thread tries to access it mid-function)?

void someFunction(const SomeObject& mustNotChange){
    bool check;
    if(mustNotChange.getNumber()==0) check == true; //sleep for 10s
    if(check && mustNotChange.getNumber()!=0) //CRASH!!!
}
4
  • 1
    AFAIK, modification of const object leads to undefined behavior: eel.is/c++draft/dcl.dcl#dcl.type.cv-4.sentence-1. Commented Jun 29, 2021 at 8:49
  • 2
    Note that C++ does not guarantee that the parameter will not change. If you, for instance, pass its address elsewhere, dereference it there, then cast to non-const, and finally modify (which results in UB), C++ allows you to do that. Commented Jun 29, 2021 at 8:57
  • EDIT: indeed I forgot to mention the parameter I would like to pass by ref (now updated) Commented Jun 29, 2021 at 9:03
  • Examples where value const X& can change in some way: lazy evaluation, function calls a callback which is modifying variable passed by argument. But his should not lead to a crash (indicated by code comment). Please provide more details of your problem: MORE CODE. Commented Jun 29, 2021 at 9:20

4 Answers 4

1

In your example const doesn't make any difference for other threads as mustNotChange is in your current function stack space (or even a register) which should not be accessible by other threads.

I assume you are more interested in the case where other threads can access the memory, something like:

void someFunction(const int& mustNotChange)
{
    //...
}

void someOtherFunction(int& mayCHange)
{
    //...
}

int main()
{
    int i = 0;
    std::thread t0([&i](){someFunction(i);});
    std::thread t1([&i](){someOtherFunction(i);});
    
    t0.join();
    t1.join();
    
    return 0;
}

In this case the const ensure that someFunction can't change the value of mustNotChange and if it does it's undefined behavior, but this doesn't offer any guarantees about other functions that can access the same memory.

As a conclusion:

  • if you don't share data (as in the same memory location) between threads as you do in your example you don't have to worry about data races
  • if you share data, but no function can change the shared data (all functions receive data as const) you don't have to worry about data races. Please note that in current example if you change i before both threads join it's still a data race!
  • if you share data and at least one function can change the data you must synchronization mechanisms.
Sign up to request clarification or add additional context in comments.

Comments

1

It is not possible to say by just looking at the code if the referred-to object can change or not. This is why it's important to design the application with concurrency in mind, to, for example, minimize explicit sharing of writable data.

It doesn't matter that an object is accessed inside a function or through a const reference, the rules are the same. In the C++ memory model, accessing the same (non-atomic) value concurrently is possible only for reading. As soon as at least one writer is involved (in any thread), no other reads or writes may happen concurrently.

Furthermore, reads and writes in different threads must be synchronized; this is known as the "happens-before" semantics; locking and releasing a mutex or waiting on an atomic are examples of synchronization events which "release" writes to other threads, which subsequently "acquire" those writes.

For more details on C++ concurrency there is a very good book "C++ Concurrency in Action". Herb Sutter also has a nice atomic<> weapons talk.

Comments

0

Basically the answer is yes; You are passing the variable by const value and hence the function to which this variable is scoped is not allowed to alter it.

1 Comment

in 99% yes but there is this 1% where this is not true. Examples: lazy evaluation, callback modifying variable which was passed by argument.
0

It is best to think of a const parameter in C++ as a promise by the function not to change the value. It doesn't mean someone else doesn't.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.