Skip to content

[DO NOT MERGE] Proposed Core reorganization for C++29 #7272

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 18 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
698b8b1
[dcl.dcl][stmt.stmt] Remove tautonyms from top level stable labels
AlisdairM Jul 28, 2024
9c3581c
[xref cpp23] Remove reference to diff against C++23
AlisdairM Jul 28, 2024
23b5f88
[config.tex] Create and apply macros to denote first and last core ch…
AlisdairM Jul 30, 2024
fda3af0
[basic.pre] Defragment specification of names and entities
AlisdairM Jul 8, 2024
0d728e1
[lex.separate][module.unit] move definitions of program and translati…
AlisdairM Jul 16, 2024
14e9147
[lex] Reorganize contents to follow grammar and phases of translation
AlisdairM Jul 30, 2024
e5af480
[lex.charset] Extract universal-character-name grammar to new subclause
AlisdairM Jun 17, 2024
61a5ad4
[lex.charset] Introduced parent [lax.char] clause for character sets …
AlisdairM Jun 17, 2024
4750450
[lex.charset] Rebase onto main
AlisdairM Jul 16, 2024
e954ff8
[module] Move modules clause to immediately follow lexing
AlisdairM Sep 29, 2024
8c913ca
[lex] Prepare to merge phase 4 preprocessor into lex
AlisdairM Sep 29, 2024
04c96f6
[lex][cpp] Merge [cpp] into [lex]
AlisdairM Sep 29, 2024
6b4fb14
Move names, linkage, and program execution into [lex]
AlisdairM Sep 30, 2024
19c9172
[basic] Reorganize subclauses for locality of reference
AlisdairM Sep 30, 2024
3e2ddc4
Reorder several lists to be by clause number
AlisdairM Oct 1, 2024
5d34bf2
Merge exception handling into statements
AlisdairM Oct 1, 2024
3eaa2da
Redistribute parts of exception handling as appropriate
AlisdairM Oct 2, 2024
66cf23b
Slightly less aggressive changes following feedback from Jens
AlisdairM Oct 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11,778 changes: 5,680 additions & 6,098 deletions source/basic.tex

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
\end{codeblock}
\end{example}

\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp23.dcl]{\ref{dcl}: declarations}

\diffref{dcl.init.list}
\change
Expand Down Expand Up @@ -359,7 +359,7 @@
\end{codeblock}
\end{example}

\rSec2[diff.cpp20.stmt]{\ref{stmt.stmt}: statements}
\rSec2[diff.cpp20.stmt]{\ref{stmt}: statements}

\diffref{stmt.ranged}
\change
Expand All @@ -383,7 +383,7 @@
\end{codeblock}
\end{example}

\rSec2[diff.cpp20.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp20.dcl]{\ref{dcl}: declarations}

\diffref{dcl.init.string}
\change
Expand Down Expand Up @@ -850,7 +850,7 @@
if those entities are only referenced in contexts
that do not result in an odr-use.

\rSec2[diff.cpp17.dcl.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp17.dcl]{\ref{dcl}: declarations}

\diffref{dcl.typedef}
\change
Expand Down Expand Up @@ -1489,7 +1489,7 @@
\tcode{::operator new(std::size_t, std::align_val_t)}
is used instead.

\rSec2[diff.cpp14.dcl.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp14.dcl]{\ref{dcl}: declarations}

\diffref{dcl.stc}
\indextext{\idxcode{register} storage class}%
Expand Down Expand Up @@ -1875,7 +1875,7 @@
revision of \Cpp{}, it yields \tcode{sizeof(const char[1])}.
\end{example}

\rSec2[diff.cpp11.dcl.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp11.dcl]{\ref{dcl}: declarations}

\diffref{dcl.constexpr}
\change
Expand Down Expand Up @@ -2117,7 +2117,7 @@
\end{codeblock}
\end{example}

\rSec2[diff.cpp03.dcl.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.cpp03.dcl]{\ref{dcl}: declarations}

\diffref{dcl.spec}
\change
Expand Down Expand Up @@ -2923,7 +2923,7 @@
\howwide
Rare.

\rSec2[diff.stat]{\ref{stmt.stmt}: statements}
\rSec2[diff.stmt]{\ref{stmt}: statements}

\diffref{stmt.switch,stmt.goto}
\change
Expand Down Expand Up @@ -2971,7 +2971,7 @@
For several years, many existing C implementations have produced warnings in
this case.

\rSec2[diff.dcl]{\ref{dcl.dcl}: declarations}
\rSec2[diff.dcl]{\ref{dcl}: declarations}

\diffref{dcl.stc}
\change
Expand Down
4 changes: 4 additions & 0 deletions source/config.tex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
%% Release date
\newcommand{\reldate}{\today}

%% Core chapters
\newcommand{\firstcorechapter}{lex}
\newcommand{\lastcorechapter}{temp}

%% Library chapters
\newcommand{\firstlibchapter}{support}
\newcommand{\lastlibchapter}{exec}
275 changes: 271 additions & 4 deletions source/declarations.tex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
%!TEX root = std.tex
\rSec0[dcl.dcl]{Declarations}%
\rSec0[dcl]{Declarations}%
\indextext{declaration|(}

\gramSec[gram.dcl]{Declarations}
Expand Down Expand Up @@ -129,7 +129,7 @@
\indextext{scope}%
Certain declarations contain one or more scopes\iref{basic.scope.scope}.
Unless otherwise stated, utterances in
\ref{dcl.dcl} about components in, of, or contained by a
\ref{dcl} about components in, of, or contained by a
declaration or subcomponent thereof refer only to those components of
the declaration that are \emph{not} nested within scopes nested within
the declaration.
Expand Down Expand Up @@ -4422,6 +4422,273 @@
\indextext{declaration!default argument|)}%
\indextext{declarator!meaning of|)}

\rSec3[except.spec]{Exception specifications}%
\indextext{exception specification|(}

\pnum
The predicate indicating whether a function cannot exit via an exception
is called the \defn{exception specification} of the function.
If the predicate is false,
the function has a
\indextext{exception specification!potentially-throwing}%
\defnx{potentially-throwing exception specification}%
{potentially-throwing!exception specification},
otherwise it has a
\indextext{exception specification!non-throwing}%
\defn{non-throwing exception specification}.
The exception specification is either defined implicitly,
or defined explicitly
by using a \grammarterm{noexcept-specifier}
as a suffix of a function declarator\iref{dcl.fct}.

\begin{bnf}
\nontermdef{noexcept-specifier}\br
\keyword{noexcept} \terminal{(} constant-expression \terminal{)}\br
\keyword{noexcept}\br
\end{bnf}

\pnum
\indextext{exception specification!noexcept!constant expression and}%
In a \grammarterm{noexcept-specifier}, the \grammarterm{constant-expression},
if supplied, shall be a contextually converted constant expression
of type \keyword{bool}\iref{expr.const};
that constant expression is the exception specification of
the function type in which the \grammarterm{noexcept-specifier} appears.
A \tcode{(} token that follows \keyword{noexcept} is part of the
\grammarterm{noexcept-specifier} and does not commence an
initializer\iref{dcl.init}.
The \grammarterm{noexcept-specifier} \keyword{noexcept}
without a \grammarterm{constant-expression}
is
equivalent to the \grammarterm{noexcept-specifier}
\tcode{\keyword{noexcept}(\keyword{true})}.
\begin{example}
\begin{codeblock}
void f() noexcept(sizeof(char[2])); // error: narrowing conversion of value 2 to type \keyword{bool}
void g() noexcept(sizeof(char)); // OK, conversion of value 1 to type \keyword{bool} is non-narrowing
\end{codeblock}
\end{example}

\pnum
If a declaration of a function
does not have a \grammarterm{noexcept-specifier},
the declaration has a potentially throwing exception specification
unless it is a destructor or a deallocation function
or is defaulted on its first declaration,
in which cases the exception specification
is as specified below
and no other declaration for that function
shall have a \grammarterm{noexcept-specifier}.
In an explicit instantiation\iref{temp.explicit}
a \grammarterm{noexcept-specifier} may be specified,
but is not required.
If a \grammarterm{noexcept-specifier} is specified
in an explicit instantiation,
the exception specification shall be the same as
the exception specification of all other declarations of that function.
A diagnostic is required only if the
exception specifications are not the same
within a single translation unit.

\pnum
\indextext{exception specification!virtual function and}%
If a virtual function has a
non-throwing exception specification,
all declarations, including the definition, of any function
that overrides that virtual function in any derived class
shall have a non-throwing
exception specification,
unless the overriding function is defined as deleted.
\begin{example}
\begin{codeblock}
struct B {
virtual void f() noexcept;
virtual void g();
virtual void h() noexcept = delete;
};

struct D: B {
void f(); // error
void g() noexcept; // OK
void h() = delete; // OK
};
\end{codeblock}

The declaration of
\tcode{D::f}
is ill-formed because it
has a potentially-throwing exception specification,
whereas
\tcode{B::f}
has a non-throwing exception specification.
\end{example}

\pnum
An expression $E$ is
\defnx{potentially-throwing}{potentially-throwing!expression} if
\begin{itemize}
\item
$E$ is a \grammarterm{throw-expression}\iref{expr.throw},
or
\item
$E$ implicitly invokes a function
(such as an overloaded operator,
an allocation function in a \grammarterm{new-expression},
a constructor for a function argument,
or a destructor if $E$ is a full-expression\iref{intro.execution})
that has a potentially-throwing exception specification,
or
\item
any of the immediate subexpressions\iref{intro.execution}
of $E$ is potentially-throwing,
or
\item
$E$ is a function call\iref{expr.call}
whose \grammarterm{postfix-expression}
has a function type,
or a pointer-to-function type,
with a potentially-throwing exception specification,
or
\item
$E$ is a \keyword{dynamic_cast} expression that casts to a reference type and
requires a runtime check\iref{expr.dynamic.cast},
or
\item
$E$ is a \keyword{typeid} expression applied to a
(possibly parenthesized) built-in unary \tcode{*} operator
applied to a pointer to a
polymorphic class type\iref{expr.typeid}.
\end{itemize}

\pnum
An implicitly-declared constructor for a class \tcode{X},
or a constructor without a \grammarterm{noexcept-specifier}
that is defaulted on its first declaration,
has a potentially-throwing exception specification
if and only if
any of the following constructs is potentially-throwing:
\begin{itemize}
\item
the invocation of a constructor selected by overload resolution
in the implicit definition of the constructor
for class \tcode{X}
to initialize a potentially constructed subobject, or
\item
a subexpression of such an initialization,
such as a default argument expression, or,
\item
for a default constructor, a default member initializer.
\end{itemize}
\begin{note}
Even though destructors for fully-constructed subobjects
are invoked when an exception is thrown
during the execution of a constructor\iref{except.ctor},
their exception specifications do not contribute
to the exception specification of the constructor,
because an exception thrown from such a destructor
would call the function \tcode{std::terminate}
rather than escape the constructor\iref{except.throw,except.terminate}.
\end{note}

\pnum
The exception specification for an implicitly-declared destructor,
or a destructor without a \grammarterm{noexcept-specifier},
is potentially-throwing if and only if
any of the destructors
for any of its potentially constructed subobjects
has a potentially-throwing exception specification or
the destructor is virtual and the destructor of any virtual base class
has a potentially-throwing exception specification.

\pnum
The exception specification for an implicitly-declared assignment operator,
or an assignment-operator without a \grammarterm{noexcept-specifier}
that is defaulted on its first declaration,
is potentially-throwing if and only if
the invocation of any assignment operator
in the implicit definition is potentially-throwing.

\pnum
A deallocation function\iref{basic.stc.dynamic.deallocation}
with no explicit \grammarterm{noexcept-specifier}
has a non-throwing exception specification.

\pnum
The exception specification for a comparison operator function\iref{over.binary}
without a \grammarterm{noexcept-specifier}
that is defaulted on its first declaration
is potentially-throwing if and only if
any expression
in the implicit definition is potentially-throwing.

\pnum
\begin{example}
\begin{codeblock}
struct A {
A(int = (A(5), 0)) noexcept;
A(const A&) noexcept;
A(A&&) noexcept;
~A();
};
struct B {
B() noexcept;
B(const B&) = default; // implicit exception specification is \tcode{\keyword{noexcept}(\keyword{true})}
B(B&&, int = (throw 42, 0)) noexcept;
~B() noexcept(false);
};
int n = 7;
struct D : public A, public B {
int * p = new int[n];
// \tcode{D::D()} potentially-throwing, as the \keyword{new} operator may throw \tcode{bad_alloc} or \tcode{bad_array_new_length}
// \tcode{D::D(const D\&)} non-throwing
// \tcode{D::D(D\&\&)} potentially-throwing, as the default argument for \tcode{B}'s constructor may throw
// \tcode{D::\~D()} potentially-throwing
};
\end{codeblock}
Furthermore, if
\tcode{A::\~{}A()}
were virtual,
the program would be ill-formed since a function that overrides a virtual
function from a base class
shall not have a potentially-throwing exception specification
if the base class function has a non-throwing exception specification.
\end{example}

\pnum
An exception specification is considered to be \defnx{needed}{needed!exception specification} when:
\begin{itemize}
\item in an expression, the function is selected by
overload resolution\iref{over.match,over.over};

\item the function is odr-used\iref{term.odr.use} or, if it appears in an
unevaluated operand, would be odr-used if the expression were
potentially-evaluated;

\item the exception specification is compared to that of another
declaration (e.g., an explicit specialization or an overriding virtual
function);

\item the function is defined; or

\item the exception specification is needed for a defaulted
function that calls the function.
\begin{note}
A defaulted declaration does not require the
exception specification of a base member function to be evaluated
until the implicit exception specification of the derived
function is needed, but an explicit \grammarterm{noexcept-specifier} needs
the implicit exception specification to compare against.
\end{note}
\end{itemize}
The exception specification of a defaulted
function is evaluated as described above only when needed; similarly, the
\grammarterm{noexcept-specifier} of a specialization of a function
template or member function of a class template is instantiated only when
needed.
%
\indextext{exception specification|)}
\indextext{exception handling|)}

\rSec1[dcl.init]{Initializers}%

\rSec2[dcl.init.general]{General}%
Expand Down Expand Up @@ -8827,7 +9094,7 @@
effect. The order in which the \grammarterm{attribute-token}{s} appear in an
\grammarterm{attribute-list} is not significant. If a
keyword\iref{lex.key}
or an alternative token\iref{lex.digraph} that satisfies the syntactic requirements
or an alternative token\iref{lex.operators} that satisfies the syntactic requirements
of an \grammarterm{identifier}\iref{lex.name} is
contained in
an \grammarterm{attribute-token}, it is considered an identifier. No name
Expand All @@ -8838,7 +9105,7 @@
\pnum
Each \grammarterm{attribute-specifier-seq} is said to \defn{appertain} to some entity or
statement, identified by the syntactic context
where it appears\iref{stmt.stmt,dcl.dcl,dcl.decl}.
where it appears\iref{stmt,dcl,dcl.decl}.
If an \grammarterm{attribute-specifier-seq} that appertains to some
entity or statement contains an \grammarterm{attribute} or \grammarterm{alignment-specifier} that
is not allowed to apply to that
Expand Down
Loading
Loading