Files
cppdraft_translate/cppdraft/stmt/if.md
2025-10-25 03:02:53 +03:00

147 lines
6.7 KiB
Markdown
Raw 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.

[stmt.if]
# 8 Statements [[stmt]](./#stmt)
## 8.5 Selection statements [[stmt.select]](stmt.select#stmt.if)
### 8.5.2 The if statement [stmt.if]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L307)
If the condition ([[stmt.pre]](stmt.pre "8.1Preamble")) yields true, the first
substatement is executed[.](#1.sentence-1)
If the else part of the selection
statement is present and the condition yields false, the second
substatement is executed[.](#1.sentence-2)
If the first substatement is reached via a
label, the condition is not evaluated and the second substatement is
not executed[.](#1.sentence-3)
In the second form of if statement
(the one including else), if the first substatement is also anif statement then that inner if statement shall contain
an else part[.](#1.sentence-4)[72](#footnote-72 "In other words, the else is associated with the nearest un-elsed if.")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L322)
If the if statement is of the form if constexpr,
the value of the condition
is contextually converted to bool and
the converted expression shall be a constant expression ([[expr.const]](expr.const "7.7Constant expressions"));
this
form is called a [*constexpr if*](#def:constexpr_if "8.5.2The if statement[stmt.if]") statement[.](#2.sentence-1)
If the value of the
converted condition is false, the first substatement is a[*discarded statement*](#def:discarded_statement "8.5.2The if statement[stmt.if]"), otherwise the second substatement, if
present, is a discarded statement[.](#2.sentence-2)
During the instantiation of an
enclosing templated entity ([[temp.pre]](temp.pre "13.1Preamble")), if the condition is
not value-dependent after its instantiation, the discarded substatement
(if any) is not instantiated[.](#2.sentence-3)
Each substatement of a constexpr if statement is a control-flow-limited
statement ([[stmt.label]](stmt.label "8.2Label"))[.](#2.sentence-4)
[*Example [1](#example-1)*: if constexpr (sizeof(int[2])) {} // OK, narrowing allowed — *end example*]
[*Note [1](#note-1)*:
Odr-uses ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule")) in a discarded statement do not require
an entity to be defined[.](#2.sentence-5)
— *end note*]
[*Example [2](#example-2)*: template<typename T, typename ... Rest> void g(T&& p, Rest&& ...rs) {// ... handle pif constexpr (sizeof...(rs) > 0) g(rs...); // never instantiated with an empty argument list}extern int x; // no definition of x requiredint f() {if constexpr (true)return 0; else if (x)return x; elsereturn -x;} — *end example*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L368)
An if statement of the form
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1Preamble[stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")
is equivalent to
{
[*init-statement*](stmt.pre#nt:init-statement "8.1Preamble[stmt.pre]")
if constexpropt ( [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")
}
and an if statement of the form
if constexpropt ( [*init-statement*](stmt.pre#nt:init-statement "8.1Preamble[stmt.pre]") [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]") else [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")
is equivalent to
{
[*init-statement*](stmt.pre#nt:init-statement "8.1Preamble[stmt.pre]")
if constexpropt ( [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]") ) [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]") else [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")
}
except that the [*init-statement*](stmt.pre#nt:init-statement "8.1Preamble[stmt.pre]") is
in the same scope as the [*condition*](stmt.pre#nt:condition "8.1Preamble[stmt.pre]")[.](#3.sentence-1)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L394)
An if statement of the form if consteval is called a [*consteval if statement*](#def:statement,consteval_if "8.5.2The if statement[stmt.if]")[.](#4.sentence-1)
The [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]"), if any, in a consteval if statement
shall be a [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")[.](#4.sentence-2)
[*Example [3](#example-3)*: constexpr void f(bool b) {if (true)if consteval { }else ; // error: not a [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]"); else not associated with outer if} — *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L409)
If a consteval if statement is evaluated in a context
that is manifestly constant-evaluated ([[expr.const]](expr.const "7.7Constant expressions")),
the first substatement is executed[.](#5.sentence-1)
[*Note [2](#note-2)*:
The first substatement is an immediate function context[.](#5.sentence-2)
— *end note*]
Otherwise, if the else part of the selection statement is present,
then the second substatement is executed[.](#5.sentence-3)
Each substatement of a consteval if statement is a control-flow-limited
statement ([[stmt.label]](stmt.label "8.2Label"))[.](#5.sentence-4)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/statements.tex#L421)
An if statement of the form
if ! consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")
is not itself a consteval if statement,
but is equivalent to the consteval if statement
if consteval { } else [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")
An if statement of the form
if ! consteval [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")1 else [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")2
is not itself a consteval if statement,
but is equivalent to the consteval if statement
if consteval [*statement*](stmt.pre#nt:statement "8.1Preamble[stmt.pre]")2 else [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]")1
[72)](#footnote-72)[72)](#footnoteref-72)
In other words, the else is associated with the nearest un-elsedif[.](#footnote-72.sentence-1)