...
| 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" |
...