mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2025-12-17 04:44:34 +03:00
Modify ES.20 to address #1400
This commit is contained in:
@@ -10528,6 +10528,31 @@ Assuming that there is a logical connection between `i` and `j`, that connection
|
|||||||
|
|
||||||
auto [i, j] = make_related_widgets(cond); // C++17
|
auto [i, j] = make_related_widgets(cond); // C++17
|
||||||
|
|
||||||
|
If the `make_related_widgets` function is otherwise redundant,
|
||||||
|
we can eliminate it by using a lambda [ES.28](#Res-lambda-init):
|
||||||
|
|
||||||
|
auto [i, j] = [x]{ return (x) ? pair{f1(),f2()} : pair{f3(),f4()} }(); // C++17
|
||||||
|
|
||||||
|
Using a value representing "uninitialized" is a symptom of a problem and not a solution:
|
||||||
|
|
||||||
|
widget i = uninit; // bad
|
||||||
|
widget j = uninit;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
use(i); // possibly used before set
|
||||||
|
// ...
|
||||||
|
|
||||||
|
if (cond) { // bad: i and j are initialized "late"
|
||||||
|
i = f1();
|
||||||
|
j = f2();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
i = f3();
|
||||||
|
j = f4();
|
||||||
|
}
|
||||||
|
|
||||||
|
Now the compiler cannot even simply detect a used-before-set. Further, we've introduced complexity in the state space for widget: which operations are valid on an `uninit` widget and which are not?
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
Complex initialization has been popular with clever programmers for decades.
|
Complex initialization has been popular with clever programmers for decades.
|
||||||
@@ -10573,6 +10598,8 @@ However, such examples do tend to leave uninitialized variables accessible, so t
|
|||||||
int buf[max] = {}; // zero all elements; better in some situations
|
int buf[max] = {}; // zero all elements; better in some situations
|
||||||
f.read(buf, max);
|
f.read(buf, max);
|
||||||
|
|
||||||
|
Because of the restrictive initialization rules for arrays and `std::array`, they offer the most commoncompelling examples of the need for this exception.
|
||||||
|
|
||||||
When feasible use a library function that is known not to overflow. For example:
|
When feasible use a library function that is known not to overflow. For example:
|
||||||
|
|
||||||
string s; // s is default initialized to ""
|
string s; // s is default initialized to ""
|
||||||
@@ -10592,27 +10619,6 @@ In the not uncommon case where the input target and the input operation get sepa
|
|||||||
|
|
||||||
A good optimizer should know about input operations and eliminate the redundant operation.
|
A good optimizer should know about input operations and eliminate the redundant operation.
|
||||||
|
|
||||||
##### Example
|
|
||||||
|
|
||||||
Using a value representing "uninitialized" is a symptom of a problem and not a solution:
|
|
||||||
|
|
||||||
widget i = uninit; // bad
|
|
||||||
widget j = uninit;
|
|
||||||
|
|
||||||
// ...
|
|
||||||
use(i); // possibly used before set
|
|
||||||
// ...
|
|
||||||
|
|
||||||
if (cond) { // bad: i and j are initialized "late"
|
|
||||||
i = f1();
|
|
||||||
j = f2();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
i = f3();
|
|
||||||
j = f4();
|
|
||||||
}
|
|
||||||
|
|
||||||
Now the compiler cannot even simply detect a used-before-set. Further, we've introduced complexity in the state space for widget: which operations are valid on an `uninit` widget and which are not?
|
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user