From Jason Turner

[dcl.attr.nodiscard]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmpt6fgyatw/{from.md → to.md} +55 -11
tmp/tmpt6fgyatw/{from.md → to.md} RENAMED
@@ -1,28 +1,72 @@
1
  ### Nodiscard attribute <a id="dcl.attr.nodiscard">[[dcl.attr.nodiscard]]</a>
2
 
3
  The *attribute-token* `nodiscard` may be applied to the *declarator-id*
4
  in a function declaration or to the declaration of a class or
5
- enumeration. It shall appear at most once in each *attribute-list* and
6
- no *attribute-argument-clause* shall be present.
7
-
8
- [*Note 1*: A nodiscard call is a function call expression that calls a
9
- function previously declared `nodiscard`, or whose return type is a
10
- possibly cv-qualified class or enumeration type marked `nodiscard`.
11
- Appearance of a nodiscard call as a potentially-evaluated
12
- discarded-value expression (Clause  [[expr]]) is discouraged unless
13
- explicitly cast to `void`. Implementations are encouraged to issue a
14
- warning in such cases. This is typically because discarding the return
15
- value of a nodiscard call has surprising consequences. — *end note*]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
 
17
  [*Example 1*:
18
 
19
  ``` cpp
 
 
 
 
 
 
 
20
  struct [[nodiscard]] error_info { ... };
21
  error_info enable_missile_safety_mode();
22
  void launch_missiles();
23
  void test_missiles() {
 
 
 
 
 
24
  enable_missile_safety_mode(); // warning encouraged
25
  launch_missiles();
26
  }
27
  error_info &foo();
28
  void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither
 
1
  ### Nodiscard attribute <a id="dcl.attr.nodiscard">[[dcl.attr.nodiscard]]</a>
2
 
3
  The *attribute-token* `nodiscard` may be applied to the *declarator-id*
4
  in a function declaration or to the declaration of a class or
5
+ enumeration. It shall appear at most once in each *attribute-list*. An
6
+ *attribute-argument-clause* may be present and, if present, shall have
7
+ the form:
8
+
9
+ ``` bnf
10
+ '(' string-literal ')'
11
+ ```
12
+
13
+ A name or entity declared without the `nodiscard` attribute can later be
14
+ redeclared with the attribute and vice-versa.
15
+
16
+ [*Note 1*: Thus, an entity initially declared without the attribute can
17
+ be marked as `nodiscard` by a subsequent redeclaration. However, after
18
+ an entity is marked as `nodiscard`, later redeclarations do not remove
19
+ the `nodiscard` from the entity. — *end note*]
20
+
21
+ Redeclarations using different forms of the attribute (with or without
22
+ the *attribute-argument-clause* or with different
23
+ *attribute-argument-clause*s) are allowed.
24
+
25
+ A *nodiscard type* is a (possibly cv-qualified) class or enumeration
26
+ type marked `nodiscard` in a reachable declaration. A *nodiscard call*
27
+ is either
28
+
29
+ - a function call expression [[expr.call]] that calls a function
30
+ declared `nodiscard` in a reachable declaration or whose return type
31
+ is a nodiscard type, or
32
+ - an explicit type conversion ([[expr.type.conv]],
33
+ [[expr.static.cast]], [[expr.cast]]) that constructs an object through
34
+ a constructor declared `nodiscard` in a reachable declaration, or that
35
+ initializes an object of a nodiscard type.
36
+
37
+ *Recommended practice:* Appearance of a nodiscard call as a
38
+ potentially-evaluated discarded-value expression [[expr.prop]] is
39
+ discouraged unless explicitly cast to `void`. Implementations should
40
+ issue a warning in such cases.
41
+
42
+ [*Note 2*: This is typically because discarding the return value of a
43
+ nodiscard call has surprising consequences. — *end note*]
44
+
45
+ The *string-literal* in a `nodiscard` *attribute-argument-clause* should
46
+ be used in the message of the warning as the rationale for why the
47
+ result should not be discarded.
48
 
49
  [*Example 1*:
50
 
51
  ``` cpp
52
+ struct [[nodiscard]] my_scopeguard { ... };
53
+ struct my_unique {
54
+ my_unique() = default; // does not acquire resource
55
+ [[nodiscard]] my_unique(int fd) { ... } // acquires resource
56
+ ~my_unique() noexcept { ... } // releases resource, if any
57
+ ...
58
+ };
59
  struct [[nodiscard]] error_info { ... };
60
  error_info enable_missile_safety_mode();
61
  void launch_missiles();
62
  void test_missiles() {
63
+ my_scopeguard(); // warning encouraged
64
+ (void)my_scopeguard(), // warning not encouraged, cast to void
65
+ launch_missiles(); // comma operator, statement continues
66
+ my_unique(42); // warning encouraged
67
+ my_unique(); // warning not encouraged
68
  enable_missile_safety_mode(); // warning encouraged
69
  launch_missiles();
70
  }
71
  error_info &foo();
72
  void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither