Files
2025-10-25 03:02:53 +03:00

5.1 KiB

[dcl.attr.nodiscard]

9 Declarations [dcl]

9.13 Attributes [dcl.attr]

9.13.9 Nodiscard attribute [dcl.attr.nodiscard]

1

#

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

An attribute-argument-clause may be present and, if present, shall have the form:

( unevaluated-string )

2

#

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]

Redeclarations using different forms of the attribute (with or without the attribute-argument-clause or with different attribute-argument-clauses) are allowed.

3

#

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.

4

#

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]

The unevaluated-string in a nodiscard attribute-argument-clause should be used in the message of the warning as the rationale for why the result should not be discarded.

5

#

[Example 1: struct nodiscard my_scopeguard { /* ... / };struct my_unique { my_unique() = default; // does not acquire resourcenodiscard 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]