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)
|
||||
{
|
||||
if (p == nullptr) throw Nullptr_error{};
|
||||
if (!p) throw Nullptr_error{};
|
||||
int n = strlen(p);
|
||||
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];
|
||||
// ... manipulate buffer ...
|
||||
X x;
|
||||
|
@ -1499,7 +1499,7 @@ Ideally, that `Expects(x >= 0)` should be part of the interface of `sqrt()` but
|
|||
|
||||
##### 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 <`.
|
||||
|
||||
##### Note
|
||||
|
@ -3214,7 +3214,7 @@ Consider:
|
|||
|
||||
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
|
||||
int length(not_null<Record*> p);
|
||||
|
@ -3301,7 +3301,7 @@ Consider:
|
|||
|
||||
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
|
||||
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
|
||||
{
|
||||
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};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
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->right, s))) return p;
|
||||
return nullptr;
|
||||
|
@ -5022,7 +5022,7 @@ Leaving behind an invalid object is asking for trouble.
|
|||
X2(const string& name)
|
||||
: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 (;;) {
|
||||
// treat the next var as a char*; no checking: a cast in disguise
|
||||
char* p = va_arg(ap, char*);
|
||||
if (p == nullptr) break;
|
||||
if (!p) break;
|
||||
cerr << p << ' ';
|
||||
}
|
||||
|
||||
|
@ -11872,7 +11872,7 @@ There are many approaches to dealing with this potential problem:
|
|||
|
||||
void f1(int* p) // deal with nullptr
|
||||
{
|
||||
if (p == nullptr) {
|
||||
if (!p) {
|
||||
// deal with nullptr (allocate, return, throw, make p point to something, whatever
|
||||
}
|
||||
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
|
||||
{
|
||||
assert(p != nullptr);
|
||||
assert(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:
|
||||
|
||||
void f3(int* p) // state that p is not supposed to be nullptr
|
||||
[[expects: p != nullptr]]
|
||||
[[expects: 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));
|
||||
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)
|
||||
{
|
||||
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
|
||||
return i;
|
||||
}
|
||||
|
@ -19450,7 +19450,7 @@ If we applied the rule, we'd get something like
|
|||
int index2(const char* p)
|
||||
{
|
||||
int i;
|
||||
if (p == nullptr)
|
||||
if (!p)
|
||||
i = -1; // error indicator
|
||||
else {
|
||||
// ... 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)
|
||||
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,
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user