0

Let me define safely: doesn't return gibberish. Let's assume i have a variable of any type; for this example i'm using an int and a class

class Example
  {
  int a;
  public: 
    void set_int(int b) { a = b; }
    void do_stuff() { std::cout << a << std::endl; }
  }

If one thread unpredictively calls set_int, and another thread periodically calls do_stuff(), in case a collision happens am i simply going to print to console the older value of a (which in my case is still fine), or am i going to see totally unpredictable values on a?

Note that any change made to the class i'm talking about is only a value reassignment, there's no addition of elements to containers or stuff like that, no indexes or iterators involved; just mere values.

Barnack
  • 921
  • 1
  • 8
  • 20
  • 3
    Data race exhibits undefined behavior. Undefined behavior means anything can happen, from "seems to work" to [nasal demons](http://www.catb.org/jargon/html/N/nasal-demons.html). Don't attempt to reason that this one is not that bad - there ain't no such thing as a [benign data race](https://software.intel.com/en-us/blogs/2013/01/06/benign-data-races-what-could-possibly-go-wrong). Just say No. – Igor Tandetnik Jan 12 '20 at 18:40
  • @dandan78 for some reason i kept finding a question about concurrent reads without writes and i couldn't find that one you linked. Should i flag my own question as duplicate to help future searches? – Barnack Jan 12 '20 at 18:50

1 Answers1

4

Can one thread “safely” read from a variable written on by another thread without guards?

Yes, with the pre-condition that both operations are ordered in relation to one another. Generally, a requirement for that condition to be satisfied is for both operations to be atomic, and that is satisfied for atomic types. Read and write operations on non-atomic types are unordered in relation to operations in other threads unless that ordering is established through mutual exclusion (see std::mutex). Unordered operations across threads where at least one is write result in undefined behaviour.

int that you used in the example is not guaranteed to be an atomic type in C++. Instances of the std::atomic template are guaranteed to be atomic - well, the standard ones at least; if you define custom specialisations, then make sure to use mutual exclusion to keep them atomic to avoid confusion.

eerorika
  • 232,697
  • 12
  • 197
  • 326