[dcl.attr.nodiscard]

9 Declarations [dcl]

9.13 Attributes [dcl.attr]

9.13.9 Nodiscard attribute [dcl.attr.nodiscard]

The attribute-token nodiscard may be applied to a function or a lambda call operator or to the declaration of a class or enumeration.

A name or entity declared without the nodiscard attribute can later be redeclared with the attribute and vice-versa.

[Note 1: 

Thus, an entity initially declared without the attribute can be marked as nodiscard by a subsequent redeclaration.

However, after an entity is marked as nodiscard, later redeclarations do not remove the nodiscard from the entity.

— end note]

A nodiscard type is a (possibly cv-qualified) class or enumeration type marked nodiscard in a reachable declaration.

A nodiscard call is either

  • a function call expression ([expr.call]) that calls a function declared nodiscard in a reachable declaration or whose return type is a nodiscard type, or
  • an explicit type conversion ([expr.type.conv], [expr.static.cast], [expr.cast]) that constructs an object through a constructor declared nodiscard in a reachable declaration, or that initializes an object of a nodiscard type.

Recommended practice: Appearance of a nodiscard call as a potentially-evaluated discarded-value expression ([expr.prop]) of non-void type is discouraged unless explicitly cast to void.

Implementations should issue a warning in such cases.

The value of a has-attribute-expression for the nodiscard attribute should be 0 unless the implementation can issue such warnings.

[Note 2: 

This is typically because discarding the return value of a nodiscard call has surprising consequences.

— end note]

[Example 1: struct [[nodiscard]] my_scopeguard { /* ... */ }; struct my_unique { my_unique() = default; // does not acquire resource [[nodiscard]] my_unique(int fd) { /* ... */ } // acquires resource ~my_unique() noexcept { /* ... */ } // releases resource, if any /* ... */ }; struct [[nodiscard]] error_info { /* ... */ }; error_info enable_missile_safety_mode(); void launch_missiles(); void test_missiles() { my_scopeguard(); // warning encouraged (void)my_scopeguard(), // warning not encouraged, cast to void launch_missiles(); // comma operator, statement continues my_unique(42); // warning encouraged my_unique(); // warning not encouraged enable_missile_safety_mode(); // warning encouraged launch_missiles(); } error_info &foo(); void f() { foo(); } // warning not encouraged: not a nodiscard call, because neither // the (reference) return type nor the function is declared nodiscard — end example]