Skip to content

Commit 59eacc8

Browse files
committed
Merged F.22 into F.15 (issue #1)
1 parent 7fb7db3 commit 59eacc8

File tree

1 file changed

+26
-35
lines changed

1 file changed

+26
-35
lines changed

CppCoreGuidelines.md

Lines changed: 26 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1785,7 +1785,6 @@ Argument passing rules:
17851785
* [F.17: Use a `not_null<T>` to indicate "null" is not a valid value](#Rf-nullptr)
17861786
* [F.18: Use a `span<T>` or a `span_p<T>` to designate a half-open sequence](#Rf-range)
17871787
* [F.19: Use a `zstring` or a `not_null<zstring>` to designate a C-style string](#Rf-string)
1788-
* [F.22: Use `T&` for an in-out-parameter](#Rf-T-ref)
17891788
* [F.23: Use `T&` for an out-parameter that is expensive to move (only)](#Rf-T-return-out)
17901789
* [F.24: Use a `TP&&` parameter when forwarding (only)](#Rf-pass-ref-ref)
17911790
* [F.25: Use a `T&&` parameter together with `move` for rare optimization opportunities](#Rf-pass-ref-move)
@@ -2216,6 +2215,31 @@ If you have multiple values to return, [use a tuple](#Rf-T-multi) or similar mul
22162215

22172216
**For an "in-out" parameter:** Pass by non-`const` reference. This makes it clear to callers that the object is assumed to be modified.
22182217

2218+
##### Example
2219+
2220+
void update(Record& r); // assume that update writes to r
2221+
2222+
##### Note
2223+
2224+
A `T&` argument can pass information into a function as well as well as out of it.
2225+
Thus `T&` could be an in-out-parameter. That can in itself be a problem and a source of errors:
2226+
2227+
void f(string& s)
2228+
{
2229+
s = "New York"; // non-obvious error
2230+
}
2231+
2232+
void g()
2233+
{
2234+
string buffer = ".................................";
2235+
f(buffer);
2236+
// ...
2237+
}
2238+
2239+
Here, the writer of `g()` is supplying a buffer for `f()` to fill, but `f()` simply replaces it (at a somewhat higher cost than a simple copy of the characters).
2240+
If the writer of `g()` makes an assumption about the size of `buffer` a bad logic error can happen.
2241+
2242+
22192243
**For an "input-only" value:** If the object is cheap to copy, pass by value; nothing beats the simplicity and safety of copying, and for small objects (up to two or three words) it is also faster than passing by reference.
22202244
Otherwise, pass by `const&` which is always cheap for larger objects. Both let the caller know that a function will not modify the argument, and both allow initialization by rvalues.
22212245
What is "cheap to copy" depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value.
@@ -2280,6 +2304,7 @@ If you need the notion of an optional value, use a pointer, `std::optional`, or
22802304
* (Simple) ((Foundation)) Warn when a parameter being passed by value has a size greater than `4 * sizeof(int)`.
22812305
Suggest using a `const` reference instead.
22822306
* (Simple) ((Foundation)) Warn when a `const` parameter being passed by reference has a size less than `3 * sizeof(int)`. Suggest passing by value instead.
2307+
* (Moderate) ((Foundation)) Warn about functions with non-`const` reference arguments that do *not* write to them.
22832308

22842309

22852310
**See also**: [implicit arguments](#Ri-explicit).
@@ -2418,40 +2443,6 @@ When I call `length(s)` should I test for `s == nullptr` first? Should the imple
24182443
**See also**: [Support library](#S-gsl).
24192444

24202445

2421-
### <a name="Rf-T-ref"></a> F.22: Use a `T&` for an in-out-parameter
2422-
2423-
##### Reason
2424-
2425-
A called function can write to a non-`const` reference argument, so assume that it does.
2426-
2427-
##### Example
2428-
2429-
void update(Record& r); // assume that update writes to r
2430-
2431-
##### Note
2432-
2433-
A `T&` argument can pass information into a function as well as well as out of it.
2434-
Thus `T&` could be and in-out-parameter. That can in itself be a problem and a source of errors:
2435-
2436-
void f(string& s)
2437-
{
2438-
s = "New York"; // non-obvious error
2439-
}
2440-
2441-
string g()
2442-
{
2443-
string buffer = ".................................";
2444-
f(buffer);
2445-
// ...
2446-
}
2447-
2448-
Here, the writer of `g()` is supplying a buffer for `f()` to fill, but `f()` simply replaces it (at a somewhat higher cost than a simple copy of the characters).
2449-
If the writer of `g()` makes an assumption about the size of `buffer` a bad logic error can happen.
2450-
2451-
##### Enforcement
2452-
2453-
* (Moderate) ((Foundation)) Warn about functions with non-`const` reference arguments that do *not* write to them.
2454-
24552446
### <a name="Rf-T-return-out"></a> F.23: Use `T&` for an out-parameter that is expensive to move (only)
24562447

24572448
##### Reason

0 commit comments

Comments
 (0)