Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Minor edits

...

Code Block
bgColor#FFcccc
langc
struct multi_threaded_flags {
  unsigned int flag1 : 2;
  unsigned int flag2 : 2;
};

struct multi_threaded_flags flags;

intvoid thread1(void *arg) {
  flags.flag1 = 1;
  return 0;
}

intvoid thread2(void *arg) {
  flags.flag2 = 2;
  return 0;
}

For example, the following instruction sequence is possible:

...

Code Block
bgColor#ccccff
langc
#include <mutex>
 
struct multi_threaded_flags {
  unsigned int flag1 : 2;
  unsigned int flag2 : 2;
};

struct mtf_mutex {
  struct multi_threaded_flags s;
  std::mutex mutex;
};

struct mtf_mutex flags;

intvoid thread1(void *arg) {
  std::lock_guard<std::mutex> lk(flags.mutex);
  flags.s.flag1 = 1;
  return 0;
}
 
intvoid thread2(void *arg) {
  std::lock_guard<std::mutex> lk(flags.mutex);
  flags.s.flag2 = 2;
  return 0;
}

Compliant Solution (C++11)

...

Code Block
bgColor#ccccff
langc
struct multi_threaded_flags {
  unsigned char flag1;
  unsigned char flag2;
};
 
struct multi_threaded_flags flags;
 
intvoid thread1(void *arg) {
  flags.flag1 = 1;
  return 0;
}

intvoid thread2(void *arg) {
  flags.flag2 = 2;
  return 0;
}

Unlike earlier versions of the standard, C++11 and later explicitly define a memory location and provide the following note in [intro.memory] paragraph 4 [ISO/IEC 14882-2014]:

...

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Bibliography

[ISO/IEC 14882-20152014][intro.memory]Subclause 1.7, "The C++ memory model"

 

...