...
Code Block | ||||
---|---|---|---|---|
| ||||
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 | ||||
---|---|---|---|---|
| ||||
#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 | ||||
---|---|---|---|---|
| ||||
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" |
...