2 <clause number="14.15" title="Constant expressions">
3 <paragraph>A <non_terminal where="14.15">constant-expression</non_terminal> is an expression that can be fully evaluated at compile-time. <grammar_production><name><non_terminal where="14.15">constant-expression</non_terminal></name> : <rhs><non_terminal where="14.14">expression</non_terminal></rhs></grammar_production></paragraph>
4 <paragraph>The type of a constant expression can be one of the following: <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>int</keyword>, <keyword>uint</keyword>, <keyword>long</keyword>, <keyword>ulong</keyword>, <keyword>char</keyword>, <keyword>float</keyword>, <keyword>double</keyword>, <keyword>decimal</keyword>, <keyword>bool</keyword>, string, any enumeration type, or the null type. The following constructs are permitted in constant expressions: <list><list_item> Literals (including the null literal). </list_item><list_item> References to const members of class and struct types. </list_item><list_item> References to members of enumeration types. </list_item><list_item> Parenthesized sub-expressions, which are themselves constant expressions. </list_item><list_item> Cast expressions, provided the target type is one of the types listed above. </list_item><list_item> The predefined +, -, !, and ~ unary operators. </list_item><list_item> The predefined +, -, *, /, %, <<, >>, &, |, ^, &&, ||, ==, !=, <, >, <=, and >= binary operators, provided each operand is of a type listed above. </list_item><list_item> The ?: conditional operator. </list_item></list></paragraph>
5 <paragraph>Whenever an expression is of one of the types listed above and contains only the constructs listed above, the expression is evaluated at compile-time. This is true even if the expression is a sub-expression of a larger expression that contains non-constant constructs. </paragraph>
6 <paragraph>The compile-time evaluation of constant expressions uses the same rules as run-time evaluation of non-constant expressions, except that where run-time evaluation would have thrown an exception, compile-time evaluation causes a compile-time error to occur. </paragraph>
7 <paragraph>Unless a constant expression is explicitly placed in an unchecked context, overflows that occur in <non_terminal where="11.1">integral-type</non_terminal> arithmetic operations and conversions during the compile-time evaluation of the expression always cause compile-time errors (<hyperlink>14.5.12</hyperlink>). </paragraph>
8 <paragraph>Constant expressions occur in the contexts listed below. In these contexts, a compile-time error occurs if an expression cannot be fully evaluated at compile-time. <list><list_item> Constant declarations (<hyperlink>17.3</hyperlink>). </list_item><list_item> Enumeration member declarations (<hyperlink>21.30</hyperlink>). </list_item><list_item> case labels of a switch statement (<hyperlink>15.7.2</hyperlink>). </list_item><list_item> goto case statements (<hyperlink>15.9.3</hyperlink>). </list_item><list_item> Dimension lengths in an array creation expression (<hyperlink>14.5.10.2</hyperlink>) that includes an initializer. </list_item><list_item> Attributes (<hyperlink>24</hyperlink>). </list_item></list></paragraph>
9 <paragraph>An implicit constant expression conversion (<hyperlink>13.1.6</hyperlink>) permits a constant expression of type <keyword>int</keyword> to be converted to <keyword>sbyte</keyword>, <keyword>byte</keyword>, <keyword>short</keyword>, <keyword>ushort</keyword>, <keyword>uint</keyword>, or <keyword>ulong</keyword>, provided the value of the constant expression is within the range of the destination type. </paragraph>