mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
This commit is contained in:
parent
9c98f9679c
commit
da3b6b98bc
|
@ -1015,10 +1015,10 @@ Time and space that you spend well to achieve a goal (e.g., speed of development
|
||||||
|
|
||||||
X waste(const char* p)
|
X waste(const char* p)
|
||||||
{
|
{
|
||||||
if (p == nullptr) throw Nullptr_error{};
|
if (!p) throw Nullptr_error{};
|
||||||
int n = strlen(p);
|
int n = strlen(p);
|
||||||
auto buf = new char[n];
|
auto buf = new char[n];
|
||||||
if (buf == nullptr) throw Allocation_error{};
|
if (!buf) throw Allocation_error{};
|
||||||
for (int i = 0; i < n; ++i) buf[i] = p[i];
|
for (int i = 0; i < n; ++i) buf[i] = p[i];
|
||||||
// ... manipulate buffer ...
|
// ... manipulate buffer ...
|
||||||
X x;
|
X x;
|
||||||
|
@ -1499,7 +1499,7 @@ Ideally, that `Expects(x >= 0)` should be part of the interface of `sqrt()` but
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
|
||||||
Prefer a formal specification of requirements, such as `Expects(p != nullptr);`.
|
Prefer a formal specification of requirements, such as `Expects(p);`.
|
||||||
If that is infeasible, use English text in comments, such as `// the sequence [p:q) is ordered using <`.
|
If that is infeasible, use English text in comments, such as `// the sequence [p:q) is ordered using <`.
|
||||||
|
|
||||||
##### Note
|
##### Note
|
||||||
|
@ -3214,7 +3214,7 @@ Consider:
|
||||||
|
|
||||||
int length(Record* p);
|
int length(Record* p);
|
||||||
|
|
||||||
When I call `length(p)` should I test for `p == nullptr` first? Should the implementation of `length()` test for `p == nullptr`?
|
When I call `length(p)` should I check if `p` is `nullptr` first? Should the implementation of `length()` check if `p` is `nullptr`?
|
||||||
|
|
||||||
// it is the caller's job to make sure p != nullptr
|
// it is the caller's job to make sure p != nullptr
|
||||||
int length(not_null<Record*> p);
|
int length(not_null<Record*> p);
|
||||||
|
@ -3301,7 +3301,7 @@ Consider:
|
||||||
|
|
||||||
int length(const char* p);
|
int length(const char* p);
|
||||||
|
|
||||||
When I call `length(s)` should I test for `s == nullptr` first? Should the implementation of `length()` test for `p == nullptr`?
|
When I call `length(s)` should I check if `s` is `nullptr` first? Should the implementation of `length()` check if `p` is `nullptr`?
|
||||||
|
|
||||||
// the implementor of length() must assume that p == nullptr is possible
|
// the implementor of length() must assume that p == nullptr is possible
|
||||||
int length(zstring p);
|
int length(zstring p);
|
||||||
|
@ -3389,7 +3389,7 @@ Sometimes having `nullptr` as an alternative to indicated "no object" is useful,
|
||||||
|
|
||||||
string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string
|
string zstring_to_string(zstring p) // zstring is a char*; that is a C-style string
|
||||||
{
|
{
|
||||||
if (p == nullptr) return string{}; // p might be nullptr; remember to check
|
if (!p) return string{}; // p might be nullptr; remember to check
|
||||||
return string{p};
|
return string{p};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3422,7 +3422,7 @@ Returning a `T*` to transfer ownership is a misuse.
|
||||||
|
|
||||||
Node* find(Node* t, const string& s) // find s in a binary tree of Nodes
|
Node* find(Node* t, const string& s) // find s in a binary tree of Nodes
|
||||||
{
|
{
|
||||||
if (t == nullptr || t->name == s) return t;
|
if (!t || t->name == s) return t;
|
||||||
if ((auto p = find(t->left, s))) return p;
|
if ((auto p = find(t->left, s))) return p;
|
||||||
if ((auto p = find(t->right, s))) return p;
|
if ((auto p = find(t->right, s))) return p;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -5022,7 +5022,7 @@ Leaving behind an invalid object is asking for trouble.
|
||||||
X2(const string& name)
|
X2(const string& name)
|
||||||
:f{fopen(name.c_str(), "r")}
|
:f{fopen(name.c_str(), "r")}
|
||||||
{
|
{
|
||||||
if (f == nullptr) throw runtime_error{"could not open" + name};
|
if (!f) throw runtime_error{"could not open" + name};
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10649,7 +10649,7 @@ Requires messy cast-and-macro-laden code to get working right.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// treat the next var as a char*; no checking: a cast in disguise
|
// treat the next var as a char*; no checking: a cast in disguise
|
||||||
char* p = va_arg(ap, char*);
|
char* p = va_arg(ap, char*);
|
||||||
if (p == nullptr) break;
|
if (!p) break;
|
||||||
cerr << p << ' ';
|
cerr << p << ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11872,7 +11872,7 @@ There are many approaches to dealing with this potential problem:
|
||||||
|
|
||||||
void f1(int* p) // deal with nullptr
|
void f1(int* p) // deal with nullptr
|
||||||
{
|
{
|
||||||
if (p == nullptr) {
|
if (!p) {
|
||||||
// deal with nullptr (allocate, return, throw, make p point to something, whatever
|
// deal with nullptr (allocate, return, throw, make p point to something, whatever
|
||||||
}
|
}
|
||||||
int x = *p;
|
int x = *p;
|
||||||
|
@ -11887,7 +11887,7 @@ There are two potential problems with testing for `nullptr`:
|
||||||
|
|
||||||
void f2(int* p) // state that p is not supposed to be nullptr
|
void f2(int* p) // state that p is not supposed to be nullptr
|
||||||
{
|
{
|
||||||
assert(p != nullptr);
|
assert(p);
|
||||||
int x = *p;
|
int x = *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11895,7 +11895,7 @@ This would carry a cost only when the assertion checking was enabled and would g
|
||||||
This would work even better if/when C++ gets direct support for contracts:
|
This would work even better if/when C++ gets direct support for contracts:
|
||||||
|
|
||||||
void f3(int* p) // state that p is not supposed to be nullptr
|
void f3(int* p) // state that p is not supposed to be nullptr
|
||||||
[[expects: p != nullptr]]
|
[[expects: p]]
|
||||||
{
|
{
|
||||||
int x = *p;
|
int x = *p;
|
||||||
}
|
}
|
||||||
|
@ -15453,7 +15453,7 @@ In such cases, "crashing" is simply leaving error handling to the next level of
|
||||||
{
|
{
|
||||||
// ...
|
// ...
|
||||||
p = static_cast<X*>(malloc(n, X));
|
p = static_cast<X*>(malloc(n, X));
|
||||||
if (p == nullptr) abort(); // abort if memory is exhausted
|
if (!p) abort(); // abort if memory is exhausted
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19440,7 +19440,7 @@ Of course many simple functions will naturally have just one `return` because of
|
||||||
|
|
||||||
int index(const char* p)
|
int index(const char* p)
|
||||||
{
|
{
|
||||||
if (p == nullptr) return -1; // error indicator: alternatively "throw nullptr_error{}"
|
if (!p) return -1; // error indicator: alternatively "throw nullptr_error{}"
|
||||||
// ... do a lookup to find the index for p
|
// ... do a lookup to find the index for p
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -19450,7 +19450,7 @@ If we applied the rule, we'd get something like
|
||||||
int index2(const char* p)
|
int index2(const char* p)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (p == nullptr)
|
if (!p)
|
||||||
i = -1; // error indicator
|
i = -1; // error indicator
|
||||||
else {
|
else {
|
||||||
// ... do a lookup to find the index for p
|
// ... do a lookup to find the index for p
|
||||||
|
@ -20033,7 +20033,7 @@ Use `not_null<zstring>` for C-style strings that cannot be `nullptr`. ??? Do we
|
||||||
These assertions are currently macros (yuck!) and must appear in function definitions (only)
|
These assertions are currently macros (yuck!) and must appear in function definitions (only)
|
||||||
pending standard committee decisions on contracts and assertion syntax.
|
pending standard committee decisions on contracts and assertion syntax.
|
||||||
See [the contract proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0380r1.pdf); using the attribute syntax,
|
See [the contract proposal](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0380r1.pdf); using the attribute syntax,
|
||||||
for example, `Expects(p != nullptr)` will become `[[expects: p != nullptr]]`.
|
for example, `Expects(p)` will become `[[expects: p]]`.
|
||||||
|
|
||||||
## <a name="SS-utilities"></a>GSL.util: Utilities
|
## <a name="SS-utilities"></a>GSL.util: Utilities
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user