On this page
if statement
Conditionally executes another statement.
Used where code needs to be executed based on a run-timeor compile-time(since C++17) condition, or whether the if statement is evaluated in a manifestly constant-evaluated context(since C++23).
Syntax
attr (optional) if constexpr (optional) ( init-statement (optional) condition ) statement-true |
(1) | |
attr (optional) if constexpr (optional) ( init-statement (optional) condition ) statement-true else statement-false |
(2) | |
attr (optional) if ! (optional) consteval compound-statement |
(3) | (since C++23) |
attr (optional) if ! (optional) consteval compound-statement else statement |
(4) | (since C++23) |
attr | - | (since C++11) any number of attributes | ||
constexpr |
- | (since C++17) if present, the statement becomes a constexpr if statement | ||
init-statement | - | (since C++17) either
; , which is why it is often described informally as an expression or a declaration followed by a semicolon. |
||
condition | - | one of
|
||
statement-true | - | any statement (often a compound statement), which is executed if condition evaluates to true |
||
statement-false | - | any statement (often a compound statement), which is executed if condition evaluates to false |
||
compound-statement | - | any compound statement, which is executed if the if-statement
|
||
statement | - | any statement (must be a compound statement, see below), which is executed if the if-statement
|
Explanation
If the condition yields true
after conversion to bool
, statement-true is executed.
If the else part of the if statement is present and condition yields false
after conversion to bool
, statement-false is executed.
In the second form of if statement (the one including else), if statement-true is also an if statement then that inner if statement must contain an else part as well (in other words, in nested if-statements, the else is associated with the closest if that doesn't have an else).
#include <iostream>
int main()
{
// simple if-statement with an else clause
int i = 2;
if (i > 2)
std::cout << i << " is greater than 2\n";
else
std::cout << i << " is not greater than 2\n";
// nested if-statement
int j = 1;
if (i > 1)
if (j > 2)
std::cout << i << " > 1 and " << j << " > 2\n";
else // this else is part of if (j > 2), not of if (i > 1)
std::cout << i << " > 1 and " << j << " <= 2\n";
// declarations can be used as conditions with dynamic_cast
struct Base
{
virtual ~Base() {}
};
struct Derived : Base
{
void df() { std::cout << "df()\n"; }
};
Base* bp1 = new Base;
Base* bp2 = new Derived;
if (Derived* p = dynamic_cast<Derived*>(bp1)) // cast fails, returns nullptr
p->df(); // not executed
if (auto p = dynamic_cast<Derived*>(bp2)) // cast succeeds
p->df(); // executed
}
Output:
2 is not greater than 2
2 > 1 and 1 <= 2
df()
If statements with initializerIf init-statement is used, the if statement is equivalent to
or
except that names declared by the init-statement (if init-statement is a declaration) and names declared by condition (if condition is a declaration) are in the same scope, which is also the scope of both statements.
|
(since C++17) |
Constexpr ifThe statement that begins with In a constexpr if statement, the value of condition must be a contextually converted constant expression of type The return statements in a discarded statement do not participate in function return type deduction:
The discarded statement can odr-use a variable that is not defined:
Outside a template, a discarded statement is fully checked.
If a constexpr if statement appears inside a templated entity, and if condition is not value-dependent after instantiation, the discarded statement is not instantiated when the enclosing template is instantiated.
Note: an example where the condition remains value-dependent after instantiation is a nested template, e.g.
Note: the discarded statement cannot be ill-formed for every possible specialization:
The common workaround before the implementation of CWG2518 for such a catch-all statement is a type-dependent expression that is always
Labels (goto targets, Note: a typedef declaration or alias declaration(since C++23) can be used as the init-statement of a constexpr if statement to reduce the scope of the type alias. |
(since C++17) |
Consteval ifThe statement that begins with
both compound-statement and statement (if any) must be compound statements. If statement is not a compound statement, it will still be treated as a part of the consteval if statement (and thus results in a compilation error):
If a consteval if statement is evaluated in a manifestly constant-evaluated context, compound-statement is executed. Otherwise, statement is executed if it is present. A If the statement begins with
compound-statement in a consteval if statement (or statement in the negative form) is in an immediate function context, in which a call to an immediate function needs not to be a constant expression.
|
(since C++23) |
Notes
If statement-true or statement-false is not a compound statement, it is treated as if it were:
if (x)
int i;
// i is no longer in scope
is the same as
if (x)
{
int i;
}
// i is no longer in scope
The scope of the name introduced by condition, if it is a declaration, is the combined scope of both statements' bodies:
if (int x = f())
{
int x; // error: redeclaration of x
}
else
{
int x; // error: redeclaration of x
}
If statement-true is entered by goto
or longjmp
, condition is not evaluated and statement-false is not executed.
Built-in conversions are not allowed in the condition of a constexpr if statement, except for non-narrowing integral conversions to |
(since C++17) (until C++23) |
|
(since C++17) |
Feature-test macro | Value | Std | Feature |
---|---|---|---|
__cpp_if_constexpr |
201606L | (C++17) | constexpr if |
__cpp_if_consteval |
202106L | (C++23) | consteval if |
Keywords
if
, else
, constexpr
, consteval
Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|---|---|---|
CWG 631 | C++98 | the control flow was unspecified if the first substatement is reached via a label |
the condition is not evaluated and the second substatement is not executed (same as in C) |
See also
(C++20)
|
detects whether the call occurs within a constant-evaluated context (function) |
C documentation for if statement |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/language/if