Merge branch 'master' into bs-local-1

This commit is contained in:
Bjarne Stroustrup
2017-02-11 13:02:30 -05:00
committed by GitHub
2 changed files with 63 additions and 19 deletions

View File

@@ -2,6 +2,7 @@
February 11, 2017 February 11, 2017
Editors: Editors:
* [Bjarne Stroustrup](http://www.stroustrup.com) * [Bjarne Stroustrup](http://www.stroustrup.com)
@@ -6690,11 +6691,49 @@ This a relatively rare use because implementation can often be organized into a
##### Reason ##### Reason
??? Without a using declaration, member functions in the derived class hide the entire inherited overload sets.
##### Example ##### Example, bad
??? #include <iostream>
class B {
public:
virtual int f(int i) { std::cout << "f(int): "; return i; }
virtual double f(double d) { std::cout << "f(double): "; return d; }
};
class D: public B {
public:
int f(int i) override { std::cout << "f(int): "; return i+1; }
};
int main()
{
D d;
std::cout << d.f(2) << '\n'; // prints "f(int): 3"
std::cout << d.f(2.3) << '\n'; // prints "f(int): 3"
}
##### Example, good
class D: public B {
public:
int f(int i) override { std::cout << "f(int): "; return i+1; }
using B::f; // exposes f(double)
};
##### Note
This issue affects both virtual and non-virtual member functions
For variadic bases, C++17 introduced a variadic form of the using-declaration,
template <class... Ts>
struct Overloader : Ts... {
using Ts::operator()...; // exposes operator() from every base
};
##### Enforcement
Diagnose name hiding
### <a name="Rh-final"></a>C.139: Use `final` sparingly ### <a name="Rh-final"></a>C.139: Use `final` sparingly
@@ -7455,9 +7494,9 @@ But heed the warning: [Avoid "naked" `union`s](#Ru-naked)
##### Example ##### Example
// Short-string optimization // Short-string optimization
constexpr size_t buffer_size = 16; // Slightly larger than the size of a pointer constexpr size_t buffer_size = 16; // Slightly larger than the size of a pointer
class Immutable_string { class Immutable_string {
public: public:
Immutable_string(const char* str) : Immutable_string(const char* str) :
@@ -7470,18 +7509,18 @@ But heed the warning: [Avoid "naked" `union`s](#Ru-naked)
strcpy_s(string_ptr, size + 1, str); strcpy_s(string_ptr, size + 1, str);
} }
} }
~Immutable_string() ~Immutable_string()
{ {
if (size >= buffer_size) if (size >= buffer_size)
delete string_ptr; delete string_ptr;
} }
const char* get_str() const const char* get_str() const
{ {
return (size < buffer_size) ? string_buffer : string_ptr; return (size < buffer_size) ? string_buffer : string_ptr;
} }
private: private:
// If the string is short enough, we store the string itself // If the string is short enough, we store the string itself
// instead of a pointer to the string. // instead of a pointer to the string.
@@ -7489,7 +7528,7 @@ But heed the warning: [Avoid "naked" `union`s](#Ru-naked)
char* string_ptr; char* string_ptr;
char string_buffer[buffer_size]; char string_buffer[buffer_size];
}; };
const size_t size; const size_t size;
}; };
@@ -11795,12 +11834,12 @@ Static tools often have many false positives and run-time tools often have a sig
We hope for better tools. We hope for better tools.
Using multiple tools can catch more problems than a single one. Using multiple tools can catch more problems than a single one.
Help the tools: There are other ways you can mitigate the chance of data races:
* less global data * Avoid global data
* fewer `static` variables * Avoid `static` variables
* more use of stack memory (and don't pass pointers around too much) * More use of value types on the stack (and don't pass pointers around too much)
* more immutable data (literals, `constexpr`, and `const`) * More use of immutable data (literals, `constexpr`, and `const`)
### <a name="Rconc-data"></a>CP.3: Minimize explicit sharing of writable data ### <a name="Rconc-data"></a>CP.3: Minimize explicit sharing of writable data
@@ -12432,7 +12471,8 @@ Thread creation is expensive.
// process // process
} }
void master(istream& is) void
(istream& is)
{ {
for (Message m; is >> m; ) for (Message m; is >> m; )
run_list.push_back(new thread(worker, m)); run_list.push_back(new thread(worker, m));
@@ -12841,7 +12881,7 @@ Example with thread-safe static local variables of C++11.
static My_class my_object; // Constructor called only once static My_class my_object; // Constructor called only once
// ... // ...
} }
class My_class class My_class
{ {
public: public:
@@ -12864,7 +12904,7 @@ Double-checked locking is easy to mess up. If you really need to write your own
##### Example, bad ##### Example, bad
Even if the following example works correctly on most hardware platforms, it is not guaranteed to work by the C++ standard. The x_init.load(memory_order_relaxed) call may see a value from outside of the lock guard. Even if the following example works correctly on most hardware platforms, it is not guaranteed to work by the C++ standard. The x_init.load(memory_order_relaxed) call may see a value from outside of the lock guard.
atomic<bool> x_init; atomic<bool> x_init;
@@ -12881,12 +12921,12 @@ Even if the following example works correctly on most hardware platforms, it is
One of the conventional patterns is below. One of the conventional patterns is below.
std::atomic<int> state; std::atomic<int> state;
// If state == SOME_ACTION_NEEDED maybe an action is needed, maybe not, we need to // If state == SOME_ACTION_NEEDED maybe an action is needed, maybe not, we need to
// check again in a lock. However, if state != SOME_ACTION_NEEDED, then we can be // check again in a lock. However, if state != SOME_ACTION_NEEDED, then we can be
// sure that an action is not needed. This is the basic assumption of double-checked // sure that an action is not needed. This is the basic assumption of double-checked
// locking. // locking.
if (state == SOME_ACTION_NEEDED) if (state == SOME_ACTION_NEEDED)
{ {
std::lock_guard<std::mutex> lock(mutex); std::lock_guard<std::mutex> lock(mutex);

View File

@@ -1,7 +1,9 @@
' '
0xFF0000 0xFF0000
0b0101'0101 0b0101'0101
10x
'14 '14
20x
2D 2D
2K 2K
2ndEdition 2ndEdition
@@ -69,6 +71,7 @@ CComPtr
cerr cerr
chrono chrono
cin cin
Clang's
class' class'
clib clib
Cline99 Cline99
@@ -492,6 +495,7 @@ toolchains
TotallyOrdered TotallyOrdered
TP TP
tradeoff tradeoff
TSAN
TSs TSs
tt tt
typeid typeid