Merge pull request #596 from tkruse/style-fix27

Style fix27
This commit is contained in:
Andrew Pardoe
2016-04-24 09:58:29 -07:00

View File

@@ -6868,6 +6868,7 @@ Union rule summary:
##### Example ##### Example
??? ???
##### Enforcement ##### Enforcement
@@ -6878,6 +6879,7 @@ Union rule summary:
##### Reason ##### Reason
Naked unions are a source of type errors. Naked unions are a source of type errors.
**Alternative**: Wrap them in a class together with a type field. **Alternative**: Wrap them in a class together with a type field.
@@ -6888,6 +6890,8 @@ Naked unions are a source of type errors.
??? ???
##### Enforcement ##### Enforcement
??? ???
@@ -10405,7 +10409,7 @@ Not all data races are as easy to spot as this one.
} }
Now, a compiler that does not know that `val` can change will most likely implement that `switch` using a jump table with five entries. Now, a compiler that does not know that `val` can change will most likely implement that `switch` using a jump table with five entries.
Then, a `val` outside the [0..4] range will cause a jump to an address that could be anywhere in the program, and execution would proceed there. Then, a `val` outside the `[0..4]` range will cause a jump to an address that could be anywhere in the program, and execution would proceed there.
Really, "all bets are off" if you get a data race. Really, "all bets are off" if you get a data race.
Actually, it can be worse still: by looking at the generated code you may be able to determine where the stray jump will go for a given value; Actually, it can be worse still: by looking at the generated code you may be able to determine where the stray jump will go for a given value;
this can be a security risk. this can be a security risk.
@@ -10865,13 +10869,13 @@ A `thread` that has not been `detach()`ed when it is destroyed terminates the pr
void f() { std::cout << "Hello "; } void f() { std::cout << "Hello "; }
struct F { struct F {
void operator()() { std::cout << "parallel world "; } void operator()() { std::cout << "parallel world "; }
}; };
int main() int main()
{ {
std::thread t1{f}; // f() executes in separate thread std::thread t1{f}; // f() executes in separate thread
std::thread t2{F()}; // F()() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread
} // spot the bugs } // spot the bugs
##### Example ##### Example
@@ -10879,13 +10883,13 @@ A `thread` that has not been `detach()`ed when it is destroyed terminates the pr
void f() { std::cout << "Hello "; } void f() { std::cout << "Hello "; }
struct F { struct F {
void operator()() { std::cout << "parallel world "; } void operator()() { std::cout << "parallel world "; }
}; };
int main() int main()
{ {
std::thread t1{f}; // f() executes in separate thread std::thread t1{f}; // f() executes in separate thread
std::thread t2{F()}; // F()() executes in separate thread std::thread t2{F()}; // F()() executes in separate thread
t1.join(); t1.join();
t2.join(); t2.join();
@@ -11071,20 +11075,20 @@ A `wait` without a condition can miss a wakeup or wake up simply to find that th
void thread1() void thread1()
{ {
while (true) { while (true) {
// do some work ... // do some work ...
std::unique_lock<std::mutex> lock(mx); std::unique_lock<std::mutex> lock(mx);
cv.notify_one(); // wake other thread cv.notify_one(); // wake other thread
} }
} }
void thread2() void thread2()
{ {
while (true) { while (true) {
std::unique_lock<std::mutex> lock(mx); std::unique_lock<std::mutex> lock(mx);
cv.wait(lock); // might block forever cv.wait(lock); // might block forever
// do work ... // do work ...
} }
} }
Here, if some other `thread` consumes `thread1`'s notification, `thread2` can wait forever. Here, if some other `thread` consumes `thread1`'s notification, `thread2` can wait forever.
@@ -11094,30 +11098,30 @@ Here, if some other `thread` consumes `thread1`'s notification, `thread2` can wa
template<typename T> template<typename T>
class Sync_queue { class Sync_queue {
public: public:
void put(const T& val); void put(const T& val);
void put(T&& val); void put(T&& val);
void get(T& val); void get(T& val);
private: private:
mutex mtx; mutex mtx;
condition_variable cond; // this controls access condition_variable cond; // this controls access
list<T> q; list<T> q;
}; };
template<typename T> template<typename T>
void Sync_queue<T>::put(const T& val) void Sync_queue<T>::put(const T& val)
{ {
lock_guard<mutex> lck(mtx); lock_guard<mutex> lck(mtx);
q.push_back(val); q.push_back(val);
cond.notify_one(); cond.notify_one();
} }
template<typename T> template<typename T>
void Sync_queue<T>::get(T& val) void Sync_queue<T>::get(T& val)
{ {
unique_lock<mutex> lck(mtx); unique_lock<mutex> lck(mtx);
cond.wait(lck,[this]{ return !q.empty(); }); // prevent spurious wakeup cond.wait(lck,[this]{ return !q.empty(); }); // prevent spurious wakeup
val=q.front(); val=q.front();
q.pop_front(); q.pop_front();
} }
Now if the queue is empty when a thread executing `get()` wakes up (e.g., because another thread has gotton to `get()` before it), Now if the queue is empty when a thread executing `get()` wakes up (e.g., because another thread has gotton to `get()` before it),
@@ -11330,15 +11334,15 @@ It's error-prone and requires expert level knowledge of language features, machi
##### Example, bad ##### Example, bad
extern atomic<Link*> head; // the shared head of a linked list extern atomic<Link*> head; // the shared head of a linked list
Link* nh = new Link(data,nullptr); // make a link ready for insertion Link* nh = new Link(data,nullptr); // make a link ready for insertion
Link* h = head.load(); // read the shared head of the list Link* h = head.load(); // read the shared head of the list
do { do {
if (h->data<=data) break; // if so, insert elsewhere if (h->data<=data) break; // if so, insert elsewhere
nh->next = h; // next element is the previous head nh->next = h; // next element is the previous head
} while (!head.compare_exchange_weak(h,nh)); // write nh to head or to h } while (!head.compare_exchange_weak(h,nh)); // write nh to head or to h
Spot the bug. Spot the bug.
It would be really hard to find through testing. It would be really hard to find through testing.