diff --git a/source/declarations.tex b/source/declarations.tex index 8725c426b0..58962c889a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -74,10 +74,16 @@ \opt{attribute-specifier-seq} decl-specifier-seq \opt{ref-qualifier} \terminal{[} identifier-list \terminal{]} initializer \terminal{;} \end{bnf} +\begin{bnf} +\nontermdef{static_assert-message}\br + unevaluated-string\br + conditional-expression +\end{bnf} + \begin{bnf} \nontermdef{static_assert-declaration}\br \keyword{static_assert} \terminal{(} constant-expression \terminal{)} \terminal{;}\br - \keyword{static_assert} \terminal{(} constant-expression \terminal{,} unevaluated-string \terminal{)} \terminal{;} + \keyword{static_assert} \terminal{(} constant-expression \terminal{,} static_assert-message \terminal{)} \terminal{;} \end{bnf} \begin{bnf} @@ -250,21 +256,66 @@ \grammarterm{explicit-specialization}\iref{temp.expl.spec}. \end{note} +\pnum +If a \grammarterm{static_assert-message} +matches the syntactic requirements of \grammarterm{unevaluated-string}, +it is an \grammarterm{unevaluated-string} and +the text of the \grammarterm{static_assert-message} is +the text of the \grammarterm{unevaluated-string}. +Otherwise, a \grammarterm{static_assert-message} shall be an expression $M$ +such that +\begin{itemize} +\item +the expression \tcode{$M$.size()} is +implicitly convertible to the type \tcode{std::size_t}, and +\item +the expression \tcode{$M$.data()} is +implicitly convertible to the type ``pointer to \tcode{\keyword{const} \keyword{char}}''. +\end{itemize} + \pnum \indextext{\idxcode{static_assert}}% In a \grammarterm{static_assert-declaration}, -the \grammarterm{constant-expression} +the \grammarterm{constant-expression} $E$ is contextually converted to \keyword{bool} and the converted expression shall be a constant expression\iref{expr.const}. -If the value of the expression when -so converted is \tcode{true} -or the expression is evaluated in the context of a template definition, -the declaration has no -effect. Otherwise, -the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed}, -the program is ill-formed, and the resulting -diagnostic message\iref{intro.compliance} should include the text of -the \grammarterm{unevaluated-string}, if one is supplied. +If the value of the expression $E$ when so converted is \tcode{true} or +the expression is evaluated in the context of a template definition, +the declaration has no effect and +the \grammarterm{static_assert-message} is +an unevaluated operand\iref{term.unevaluated.operand}. +Otherwise, +the \grammarterm{static_assert-declaration} \defnx{fails}{\idxcode{static_assert}!failed} and +\begin{itemize} +\item +the program is ill-formed, and +\item +if the \grammarterm{static_assert-message} is +a \grammarterm{conditional-expression} $M$, +\begin{itemize} +\item +\tcode{$M$.size()} shall be a converted constant expression of +type \tcode{std::size_t} and +let $N$ denote the value of that expression, +\item +\tcode{$M$.data()}, implicitly converted to +the type ``pointer to \tcode{\keyword{const} \keyword{char}}'', +shall be a core constant expression and let $D$ denote the converted expression, +\item +for each $i$ where $0 \le i < N$, +\tcode{$D$[$i$]} shall be an integral constant expression, and +\item +the text of the \grammarterm{static_assert-message} is formed by +the sequence of $N$ code units, starting at $D$, of +the ordinary literal encoding\iref{lex.charset}. +\end{itemize} +\end{itemize} + +\pnum +\recommended +When a \grammarterm{static_assert-declaration} fails, +the resulting diagnostic message should include the text of +the \grammarterm{static_assert-message}, if one is supplied. \begin{example} \begin{codeblock} static_assert(sizeof(int) == sizeof(void*), "wrong pointer size"); diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 3758cf2429..23f2fe9bbf 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1856,7 +1856,7 @@ \defnxname{cpp_rvalue_references} & \tcode{200610L} \\ \rowsep \defnxname{cpp_size_t_suffix} & \tcode{202011L} \\ \rowsep \defnxname{cpp_sized_deallocation} & \tcode{201309L} \\ \rowsep -\defnxname{cpp_static_assert} & \tcode{201411L} \\ \rowsep +\defnxname{cpp_static_assert} & \tcode{202306L} \\ \rowsep \defnxname{cpp_static_call_operator} & \tcode{202207L} \\ \rowsep \defnxname{cpp_structured_bindings} & \tcode{201606L} \\ \rowsep \defnxname{cpp_template_template_args} & \tcode{201611L} \\ \rowsep