diff options
Diffstat (limited to 'devdocs/c/language%2Fconstant_expression.html')
| -rw-r--r-- | devdocs/c/language%2Fconstant_expression.html | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/devdocs/c/language%2Fconstant_expression.html b/devdocs/c/language%2Fconstant_expression.html new file mode 100644 index 00000000..3860cf84 --- /dev/null +++ b/devdocs/c/language%2Fconstant_expression.html @@ -0,0 +1,107 @@ + <h1 id="firstHeading" class="firstHeading">Constant expressions</h1> <p>Several varieties of expressions are known as <i>constant expressions</i></p> +<h3 id="Preprocessor_constant_expression"> Preprocessor constant expression</h3> <p>The expression following <a href="../preprocessor/conditional" title="c/preprocessor/conditional"><code>#if</code> or <code>#elif</code></a> must expand to</p> +<ul> +<li> <a href="expressions#Operators" title="c/language/expressions">operators</a> other than <a href="operator_assignment" title="c/language/operator assignment">assignment</a>, <a href="operator_incdec" title="c/language/operator incdec">increment, decrement</a>, <a href="operator_other#Function_call" title="c/language/operator other">function-call</a>, or <a href="operator_other#Comma_operator" title="c/language/operator other">comma</a> whose arguments are preprocessor constant expressions </li> +<li> <a href="integer_constant" title="c/language/integer constant">integer constants</a> </li> +<li> <a href="character_constant" title="c/language/character constant">character constants</a> </li> +<li> the special preprocessor operator <code>defined</code> </li> +</ul> <p>Character constants, when evaluated in <code>#if</code>-expressions, may be interpreted in the source character set, the execution character set, or some other implementation-defined character set.</p> +<table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <p>Integer arithmetic in <code>#if</code>-expressions is performed using the semantics of <code><a href="../types/integer" title="c/types/integer">intmax_t</a></code> for signed types and <code><a href="../types/integer" title="c/types/integer">uintmax_t</a></code> for unsigned types.</p> +</td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> </table> <h3 id="Integer_constant_expression"> Integer constant expression</h3> <p>An integer constant expression is an expression that consists only of</p> +<ul> +<li> <a href="expressions#Operators" title="c/language/expressions">operators</a> other than <a href="operator_assignment" title="c/language/operator assignment">assignment</a>, <a href="operator_incdec" title="c/language/operator incdec">increment, decrement</a>, <a href="operator_other#Function_call" title="c/language/operator other">function-call</a>, or <a href="operator_other#Comma_operator" title="c/language/operator other">comma</a>, except that <a href="cast" title="c/language/cast">cast</a> operators can only cast arithmetic types to integer types unless they are part of an operand to a sizeof, <span class="t-rev-inl t-since-c11"><span>_Alignof</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> <span class="t-rev-inl t-since-c23"><span>or typeof/typeof_unqual</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> operator. </li> +<li> <a href="integer_constant" title="c/language/integer constant">integer constants</a> </li> +<li> <a href="enum" title="c/language/enum">enumeration constants</a> </li> +<li> <a href="character_constant" title="c/language/character constant">character constants</a> </li> +<li> <a href="floating_constant" title="c/language/floating constant">floating constants</a>, but only if they are immediately used as operands of casts to integer type </li> +<li> <a href="sizeof" title="c/language/sizeof"><code>sizeof</code></a> operators <span class="t-rev-inl t-since-c99"><span>whose operands are not VLA</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <ul><li> <a href="_alignof" title="c/language/ Alignof"><code>_Alignof</code></a> operators </li></ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <ul><li> named and compound literal constants that are of integer type or that are of arithmetic type and are the immediate operands of casts </li></ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <p>Integer constant expressions are evaluated at compile time. The following contexts require expressions that are known as <i>integer constant expressions</i>:</p> +<ul> +<li> The size of a <a href="bit_field" title="c/language/bit field">bit-field</a>. </li> +<li> The value of an <a href="enum" title="c/language/enum">enumeration constant</a> </li> +<li> The <code>case</code> label of a <a href="switch" title="c/language/switch">switch statement</a> </li> +<li> The size of a <span class="t-rev-inl t-since-c99"><span>non-VLA</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> array </li> +<li> Integer to pointer implicit <a href="conversion" title="c/language/conversion">conversion</a>. </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c99"> +<td> <ul><li> The index in an <a href="array_initialization" title="c/language/array initialization">array designator</a> </li></ul> </td> <td><span class="t-mark-rev t-since-c99">(since C99)</span></td> +</tr> <tr class="t-rev t-since-c11"> +<td> <ul> +<li> The first argument of <a href="_static_assert" title="c/language/ Static assert"><code>_Static_assert</code></a> </li> +<li> The integer argument of <a href="_alignas" title="c/language/ Alignas"><code>_Alignas</code></a> </li> +</ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> <tr class="t-rev t-since-c23"> +<td> <ul><li> The number of bits N of a bit-precise integer type (<code>_BitInt(N)</code>) </li></ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <h3 id="Static_initializer"> Static initializer</h3> <p>Expressions that are used in the <a href="initialization" title="c/language/initialization">initializers</a> of objects with static and thread_local <a href="storage_duration" title="c/language/storage duration">storage duration</a> <span class="t-rev-inl t-since-c23"><span>or declared with the <code>constexpr</code> storage-class specifier</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> must be either string literals or expressions that may be one of the following</p> +<div class="t-li1"> +<span class="t-li">1)</span> <i>arithmetic constant expression</i>, which is an expression of any arithmetic type that consists of <ul> +<li> <a href="expressions#Operators" title="c/language/expressions">operators</a> other than <a href="operator_assignment" title="c/language/operator assignment">assignment</a>, <a href="operator_incdec" title="c/language/operator incdec">increment, decrement</a>, <a href="operator_other#Function_call" title="c/language/operator other">function-call</a>, or <a href="operator_other#Comma_operator" title="c/language/operator other">comma</a>, except that <a href="cast" title="c/language/cast">cast</a> operators must be converting arithmetic types to other arithmetic types unless they are part of an operand to a sizeof, <span class="t-rev-inl t-since-c11"><span>_Alignof</span><span><span class="t-mark-rev t-since-c11">(since C11)</span></span></span> <span class="t-rev-inl t-since-c23"><span>or typeof/typeof_unqual</span><span><span class="t-mark-rev t-since-c23">(since C23)</span></span></span> operator </li> +<li> <a href="integer_constant" title="c/language/integer constant">integer constants</a> </li> +<li> <a href="floating_constant" title="c/language/floating constant">floating constants</a> </li> +<li> <a href="enum" title="c/language/enum">enumeration constants</a> </li> +<li> <a href="character_constant" title="c/language/character constant">character constants</a> </li> +<li> <a href="sizeof" title="c/language/sizeof"><code>sizeof</code></a> operators <span class="t-rev-inl t-since-c99"><span>whose operands are not VLA</span><span><span class="t-mark-rev t-since-c99">(since C99)</span></span></span> </li> +</ul> <table class="t-rev-begin"> <tr class="t-rev t-since-c11"> +<td> <ul><li> <a href="_alignof" title="c/language/ Alignof"><code>_Alignof</code></a> operators </li></ul> </td> <td><span class="t-mark-rev t-since-c11">(since C11)</span></td> +</tr> </table> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <ul><li> named or compound literal constants of arithmetic type </li></ul> </td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> +</div> <div class="t-li1"> +<span class="t-li">2)</span> a null pointer constant (e.g. <code><a href="../types/null" title="c/types/NULL">NULL</a></code>)</div> <div class="t-li1"> +<span class="t-li">3)</span> <i>address constant expression</i>, which is <ul> +<li> a null pointer </li> +<li> <a href="value_category" title="c/language/value category">lvalue</a> designating an object of static <a href="storage_duration" title="c/language/storage duration">storage duration</a> or a function designator, converted to a pointer either </li> +<ul> +<li> by using the unary address-of operator </li> +<li> by casting an integer constant to a pointer </li> +<li> by array-to-pointer or function-to-pointer implicit <a href="conversion" title="c/language/conversion">conversion</a> +</li> +</ul> +</ul> </div> <div class="t-li1"> +<span class="t-li">4)</span> <i>address constant expression</i> of some complete object type, plus or minus an <i>integer constant expression</i> +</div> <table class="t-rev-begin"> <tr class="t-rev t-since-c23"> +<td> <span class="t-li">5)</span> a <i>named constant</i> which is, an identifier that is <ul> +<li> an enumeration constant </li> +<li> a predefined constant (one of <code>true</code>, <code>false</code> or <code>nullptr</code>) </li> +<li> declared with storage-class specifier <code>constexpr</code> and has an object type </li> +</ul> or a postfix expression that applies the <code>.</code> member access operator to a named constant of structure or union type, even recursively. <span class="t-li">6)</span> a <i>compound literal constant</i>, which is <ul> +<li>a <a href="compound_literal" title="c/language/compound literal">compound literal</a> with storage-class specifier <code>constexpr</code> </li> +<li>a postfix expression that applies the <code>.</code> member access operator to a compound literal constant of structure or union type, even recursively.</li> +</ul> <p>A <i>structure or union constant</i> is a named constant or compound literal constant with structure or union type, respectively. If the member-access operator <code>.</code> accesses a member of a union constant, the accessed member shall be the same as the member that is initialized by the union constant’s initializer.</p> +</td> <td><span class="t-mark-rev t-since-c23">(since C23)</span></td> +</tr> </table> <div class="t-li1"> +<span class="t-li">7)</span> constant expression of one of the other forms accepted by the implementation.</div> <p>Unlike with integer constant expressions, static initializer expressions are not required to be evaluated at compile time; the compiler is at liberty to turn such initializers into executable code which is invoked prior to program startup.</p> +<div class="c source-c"><pre data-language="c">static int i = 2 || 1 / 0; // initializes i to value 1</pre></div> <p>The value of a floating-point static initializer is never less accurate than the value of the same expression executed at run time, but it may be better.</p> +<h3 id="Floating-point_constant_expressions"> Floating-point constant expressions</h3> <p>Arithmetic constant expressions of floating-point types that are not used in static initializers are always evaluated as-if during run-time and are affected by the <a href="../numeric/fenv/fe_round" title="c/numeric/fenv/FE round">current rounding</a> (if <a href="../preprocessor/impl" title="c/preprocessor/impl"><code>FENV_ACCESS</code></a> is on) and report errors as specified in <a href="../numeric/math/math_errhandling" title="c/numeric/math/math errhandling"><code>math_errhandling</code></a>.</p> +<div class="c source-c"><pre data-language="c">void f(void) +{ +#pragma STDC FENV_ACCESS ON + static float x = 0.0/0.0; // static initializer: does not raise an exception + float w[] = { 0.0/0.0 }; // raises an exception + float y = 0.0/0.0; // raises an exception + double z = 0.0/0.0; // raises an exception +}</pre></div> <h3 id="Notes"> Notes</h3> <p>If an expression evaluates to a value that is not representable by its type, it cannot be used as a constant expression.</p> +<p>Implementations may accept other forms of constant expressions. However, these constant expressions are not considered as integer constant expressions, arithmetic constant expressions, or address constant expressions, and thus cannot be used in the contexts requiring these kinds of constant expressions. For example, <code>int arr[(int)+1.0];</code> declares a VLA.</p> +<h3 id="References"> References</h3> <ul> +<li> C23 standard (ISO/IEC 9899:2023): </li> +<ul><li> 6.6 Constant expressions (p: TBD) </li></ul> +<li> C17 standard (ISO/IEC 9899:2018): </li> +<ul><li> 6.6 Constant expressions (p: 76-77) </li></ul> +<li> C11 standard (ISO/IEC 9899:2011): </li> +<ul><li> 6.6 Constant expressions (p: 106-107) </li></ul> +<li> C99 standard (ISO/IEC 9899:1999): </li> +<ul><li> 6.6 Constant expressions (p: 95-96) </li></ul> +<li> C89/C90 standard (ISO/IEC 9899:1990): </li> +<ul><li> 3.4 CONSTANT EXPRESSIONS </li></ul> +</ul> <h3 id="See_also"> See also</h3> <table class="t-dsc-begin"> <tr class="t-dsc"> <td colspan="2"> <span><a href="https://en.cppreference.com/w/cpp/language/constant_expression" title="cpp/language/constant expression">C++ documentation</a></span> for <span class=""><span>Constant expressions</span></span> </td> +</tr> </table> <div class="_attribution"> + <p class="_attribution-p"> + © cppreference.com<br>Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.<br> + <a href="https://en.cppreference.com/w/c/language/constant_expression" class="_attribution-link">https://en.cppreference.com/w/c/language/constant_expression</a> + </p> +</div> |
