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

97 lines
5.1 KiB
Markdown
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[dcl.attr.nodiscard]
# 9 Declarations [[dcl]](./#dcl)
## 9.13 Attributes [[dcl.attr]](dcl.attr#nodiscard)
### 9.13.9 Nodiscard attribute [dcl.attr.nodiscard]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10007)
The [*attribute-token*](dcl.attr.grammar#nt:attribute-token "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") nodiscard may be applied to a function or a lambda call operator or
to the declaration of a class or enumeration[.](#1.sentence-1)
An [*attribute-argument-clause*](dcl.attr.grammar#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") may be present
and, if present, shall have the form:
( [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") )
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10017)
A name or entity declared without the nodiscard attribute
can later be redeclared with the attribute and vice-versa[.](#2.sentence-1)
[*Note [1](#note-1)*:
Thus, an entity initially declared without the attribute
can be marked as nodiscard by a subsequent redeclaration[.](#2.sentence-2)
However, after an entity is marked as nodiscard,
later redeclarations do not remove the nodiscard from the entity[.](#2.sentence-3)
— *end note*]
Redeclarations using different forms of the attribute
(with or without the [*attribute-argument-clause*](dcl.attr.grammar#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") or with different [*attribute-argument-clause*](dcl.attr.grammar#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]")*s*)
are allowed[.](#2.sentence-4)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10033)
A [*nodiscard type*](#def:type,nodiscard "9.13.9Nodiscard attribute[dcl.attr.nodiscard]") is
a (possibly cv-qualified) class or enumeration type
marked nodiscard in a reachable declaration[.](#3.sentence-1)
A [*nodiscard call*](#def:call,nodiscard "9.13.9Nodiscard attribute[dcl.attr.nodiscard]") is either
- [(3.1)](#3.1)
a function call expression ([[expr.call]](expr.call "7.6.1.3Function call"))
that calls a function declared nodiscard in a reachable declaration or
whose return type is a nodiscard type, or
- [(3.2)](#3.2)
an explicit type
conversion ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)"), [[expr.static.cast]](expr.static.cast "7.6.1.9Static cast"), [[expr.cast]](expr.cast "7.6.3Explicit type conversion (cast notation)"))
that constructs an object through
a constructor declared nodiscard in a reachable declaration, or
that initializes an object of a nodiscard type[.](#3.sentence-2)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10051)
*Recommended practice*: Appearance of a nodiscard call as
a potentially-evaluated discarded-value expression ([[expr.prop]](expr.prop "7.2Properties of expressions"))
of non-void type
is discouraged unless explicitly cast to void[.](#4.sentence-1)
Implementations should issue a warning in such cases[.](#4.sentence-2)
The value of
a [*has-attribute-expression*](cpp.cond#nt:has-attribute-expression "15.2Conditional inclusion[cpp.cond]") for the nodiscard attribute
should be 0 unless the implementation can issue such warnings[.](#4.sentence-3)
[*Note [2](#note-2)*:
This is typically because discarding the return value
of a nodiscard call has surprising consequences[.](#4.sentence-4)
— *end note*]
The [*unevaluated-string*](lex.string.uneval#nt:unevaluated-string "5.13.6Unevaluated strings[lex.string.uneval]") in a nodiscard [*attribute-argument-clause*](dcl.attr.grammar#nt:attribute-argument-clause "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") should be used in the message of the warning
as the rationale for why the result should not be discarded[.](#4.sentence-5)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/declarations.tex#L10070)
[*Example [1](#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*]