Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
ed2affd
CWG2555 Ineffective redeclaration prevention for using-declarators
eisenwave Nov 9, 2025
05f7548
CWG2677 Replacing union subobjects
eisenwave Nov 9, 2025
5611dea
CWG2875 Missing support for round-tripping null pointer values throug…
eisenwave Nov 9, 2025
94e7e59
[diff.expr] Replace "For example" with \begin{example} environment
eisenwave Nov 9, 2025
00e313b
CWG2900 Deduction of non-type template arguments with placeholder types
eisenwave Nov 9, 2025
50a457a
CWG2929 Lifetime of trivially-destructible static or thread-local obj…
eisenwave Nov 9, 2025
ef2b72c
CWG2941 Lifetime extension for function-style cast to reference type
eisenwave Nov 9, 2025
bfdfd68
CWG3002 Template parameter/argument confusion
eisenwave Nov 9, 2025
c68fc1a
CWG3004 Pointer arithmetic on array of unknown bound
eisenwave Nov 9, 2025
8ccae3d
CWG3008 Missing Annex C entry for void object declarations
eisenwave Nov 9, 2025
e9ae510
CWG3011 Parenthesized aggregate initialization for new-expressions
eisenwave Nov 9, 2025
1d65b9b
CWG3032 Template argument disambiguation
eisenwave Nov 9, 2025
4477079
CWG3055 Misleading body for surrogate call function
eisenwave Nov 9, 2025
fef54d5
CWG3056 Missing semicolons in grammar for type-requirement
eisenwave Nov 9, 2025
608ce55
CWG3057 Ranking of derived-to-base conversions should ignore referenc…
eisenwave Nov 9, 2025
2e4b840
CWG3059 throw; in constant expressions
eisenwave Nov 9, 2025
0b67fde
CWG3060 Change in behavior for noexcept main
eisenwave Nov 9, 2025
a9e1c01
CWG3062 Overlapping specification of default template arguments
eisenwave Nov 9, 2025
57927c3
CWG3066 Declarative nested-name-specifier in explicit instantiation
eisenwave Nov 9, 2025
44dac4c
CWG3067 Array-to-pointer conversion with object type mismatch
eisenwave Nov 9, 2025
6b14a12
CWG3070 Trivial assignment can skip member subobjects
eisenwave Nov 9, 2025
b4aefb5
CWG3071 Negative tuple_size in structured bindings
eisenwave Nov 9, 2025
bc2881c
CWG3072 Incorrect examples for lambda SFINAE
eisenwave Nov 9, 2025
0e0386f
CWG3073 Dependence of R on T2 is unclear
eisenwave Nov 9, 2025
005a276
CWG3075 Unclear matching of import directive
eisenwave Nov 9, 2025
2d3256b
CWG3076 Remove unnecessary IFNDR for malformed header-name-tokens
eisenwave Nov 9, 2025
b41ea4e
CWG3077 Undesirable formation of import directive with string-literal
eisenwave Nov 9, 2025
907884d
CWG3078 Different treatment of #include pp-tokens and header-name-tokens
eisenwave Nov 9, 2025
d3429f9
CWG3079 Allow empty-declarations in anonymous unions
eisenwave Nov 9, 2025
35d632b
CWG3080 Clarify kinds of permitted template template arguments
eisenwave Nov 9, 2025
1ceaafe
CWG3081 Require glvalue when splicing direct base class relationship
eisenwave Nov 9, 2025
20991dd
CWG3083 Remove redundant restrictions on class and enum definitions
eisenwave Nov 9, 2025
b2cac60
CWG3085 Apply restriction inside for-range-declaration
eisenwave Nov 9, 2025
a6f665a
CWG3086 Destringizing should consider all sorts of encoding-prefixes
eisenwave Nov 9, 2025
e41a1c4
CWG3090 Internal linkage from header units
eisenwave Nov 9, 2025
0ae5cdb
CWG3091 Linking of translation units as sequences of tokens
eisenwave Nov 9, 2025
cf5693c
CWG3096 Value-dependence of size of structured binding pack with non-…
eisenwave Nov 9, 2025
02b6174
CWG3097 Lambda expression introduces a scope
eisenwave Nov 9, 2025
240db04
CWG3100 Destruction order for objects with static storage duration
eisenwave Nov 9, 2025
0fea012
CWG3102 Update list of void contexts
eisenwave Nov 9, 2025
14af0c1
CWG3105 Consteval destructor through immediate escalation
eisenwave Nov 9, 2025
ec799cb
CWG3106 Redundant exclusion of (non-existent) UCNs in r-char-sequences
eisenwave Nov 9, 2025
0067925
CWG3107 Misleading note "An alias template name is never deduced."
eisenwave Nov 9, 2025
795ffd0
CWG3111 Template parameter objects of array type
eisenwave Nov 9, 2025
7a9ba76
CWG3112 Introduce a term for C-style variadic functions
eisenwave Nov 9, 2025
a87b471
CWG3116 First element of an array
eisenwave Nov 9, 2025
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
143 changes: 105 additions & 38 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,8 @@
declaration,
\grammarterm{parameter-declaration-clause},
\grammarterm{statement},
\grammarterm{handler}, or
\grammarterm{handler},
\grammarterm{lambda-expression}, or
contract assertion
(as described in the following subclauses of \ref{basic.scope})
appearing in another scope, which thereby contains $S$.
Expand Down Expand Up @@ -2887,8 +2888,8 @@
\indextext{program}%
\indextext{linking}%
A \defn{program} consists of one or more translation units\iref{lex.phases}
linked together. A translation unit consists
of a sequence of declarations.
that are translated and linked together.
A translation unit consists of a sequence of declarations.

\begin{bnf}
\nontermdef{translation-unit}\br
Expand Down Expand Up @@ -3477,7 +3478,7 @@
An object that is not a subobject of any other object is called a \defn{complete
object}.
If an object is created
in storage associated with a member subobject or array element \placeholder{e}
in storage associated with a subobject \placeholder{e}
(which may or may not be within its lifetime),
the created object
is a subobject of \placeholder{e}'s containing object if
Expand All @@ -3487,8 +3488,12 @@
\item
the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and
\item
\placeholder{e} is not a potentially-overlapping subobject, and
\item
the new object is of the same type as \placeholder{e} (ignoring cv-qualification).
\end{itemize}
In this case, \placeholder{e} and the created object are
\defnadj{corresponding direct}{subobjects}{subobject}.

\pnum
\indextext{object!providing storage for}%
Expand Down Expand Up @@ -4013,22 +4018,24 @@
\end{note}

\pnum
An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if
An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if either
\begin{itemize}
\item
$o_1$ and $o_2$ are complete objects for which:
\begin{itemize}
\item $o_1$ is not const,
\item the storage that $o_2$ occupies exactly overlays
the storage that $o_1$ occupied, and

\item $o_1$ and $o_2$ are of the same type
(ignoring the top-level cv-qualifiers), and

\item $o_1$ is not a const, complete object, and

\item neither $o_1$ nor $o_2$
is a potentially-overlapping subobject\iref{intro.object}, and
(ignoring the top-level cv-qualifiers), or
\end{itemize}

\item either $o_1$ and $o_2$ are both complete objects, or
$o_1$ and $o_2$ are direct subobjects of objects $p_1$ and $p_2$, respectively,
and $p_1$ is transparently replaceable by $p_2$.
\item
$o_1$ and $o_2$ are corresponding direct subobjects\iref{intro.object} for which:
\begin{itemize}
\item the complete object of $o_1$ is not const or
\item $o_1$ is a mutable member subobject or subobject thereof.
\end{itemize}
\end{itemize}

\pnum
Expand Down Expand Up @@ -4813,7 +4820,9 @@
\item
a class member access\iref{expr.ref} using the \tcode{.} operator
where the left operand is one of these expressions and
the right operand designates a non-static data member of non-reference type,
the right operand designates
a non-static data member\iref{class.mem.general} of non-reference type or
a direct base class relationship\iref{class.derived.general},
\item
a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator
where the left operand is one of these expressions and
Expand All @@ -4831,6 +4840,15 @@
to a glvalue that refers
to the object designated by the operand, or
to its complete object or a subobject thereof,
\item
an explicit type conversion (functional notation)\iref{expr.type.conv}
to a reference type whose initializer is a \grammarterm{braced-init-list}
where the reference is
\begin{itemize}
\item bound directly to the glvalue result of one of these expressions
(necessarily the sole element of the \grammarterm{braced-init-list}) or
\item bound to the result of a temporary materialization conversion,
\end{itemize}
\item
a conditional expression\iref{expr.cond} that is a glvalue
where the second or third operand is one of these expressions, or
Expand Down Expand Up @@ -5593,20 +5611,23 @@
is an incomplete type that cannot be completed; such a type has
an empty set of values. It is used as the return
type for functions that do not return a value.
An expression of type \cv{}~\keyword{void} shall
be used only as
\begin{note}
An expression of type \cv{}~\keyword{void} can be used as
\begin{itemize}
\item an expression statement\iref{stmt.expr},
\item the expression in a \keyword{return} statement\iref{stmt.return}
for a function with the return type \cv{}~\keyword{void},
\item an operand of a comma expression\iref{expr.comma},
\item the operand of a parenthesized expression\iref{expr.prim.paren},
\item a requirement in a \keyword{requires} expression\iref{expr.prim.req.general},
\item the second or third operand of \tcode{?:}\iref{expr.cond},
\item the operand of a \keyword{typeid} expression\iref{expr.typeid},
\item the operand of a \keyword{noexcept} operator\iref{expr.unary.noexcept},
\item the operand of a \keyword{decltype} specifier\iref{dcl.type.decltype}, or
\item the operand of an explicit conversion to type
\cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}.
\end{itemize}
\end{note}

\pnum
The types denoted by \cv~\tcode{std::nullptr_t} are distinct types.
Expand Down Expand Up @@ -7171,8 +7192,13 @@
\indextext{\idxcode{main} function!implementation-defined parameters to}%
An implementation shall allow both
\begin{itemize}
\item a function of \tcode{()} returning \keyword{int} and
\item a function of \tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} returning \keyword{int}
\item
an ``optionally \tcode{noexcept} function of
\tcode{()} returning \keyword{int}'' and
\item
an ``optionally \tcode{noexcept} function of
\tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})}
returning \keyword{int}''
\end{itemize}
\indextext{\idxcode{argc}}%
\indextext{\idxcode{argv}}%
Expand Down Expand Up @@ -7490,7 +7516,7 @@
\indextext{program!termination|(}%
\indextext{object!destructor static}%
\indextext{\idxcode{main} function!return from}%
Constructed objects\iref{dcl.init}
Constructed complete objects\iref{dcl.init}
with static storage duration are destroyed
and functions registered with \tcode{std::atexit}
are called as part of a call to
Expand All @@ -7504,29 +7530,69 @@
\end{note}

\pnum
Constructed objects with thread storage duration within a given thread
Constructed complete objects with thread storage duration within a given thread
are destroyed as a result of returning from the initial function of that thread and as a
result of that thread calling \tcode{std::exit}.
The destruction of all constructed objects with thread storage
duration within that thread strongly happens before destroying
The destruction of those constructed objects
is sequenced before releasing the storage for
any object with thread storage duration within that thread\iref{basic.stc.thread}.
The destruction of those constructed objects
strongly happens before destroying
any object with static storage duration.

\pnum
If the completion of the constructor or dynamic initialization of an object with static
storage duration strongly happens before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first.
If the completion of the constructor or dynamic initialization of an object with thread
storage duration is sequenced before that of another, the completion of the destructor
of the second is sequenced before the initiation of the destructor of the first.
The destruction of a complete object with thread storage duration within a given thread
and having constant destruction\iref{expr.const}
is sequenced after the destruction of any other complete object
with thread storage duration within the thread.
The destruction of a complete object with static storage duration
and having constant destruction
is sequenced after the destruction of any other complete object
with static storage duration
and after any call to a function passed to \tcode{std::atexit}.
The sequencing rules in the remainder of this subclause
apply only to complete objects not having constant destruction.

\pnum
If the deemed construction\iref{dcl.init.general} of a complete object with static
storage duration strongly happens before that of another, the completion of the destruction
of the second is sequenced before the initiation of the destruction of the first.
If the deemed construction of a complete object with thread
storage duration is sequenced before that of another, the completion of the destruction
of the second is sequenced before the initiation of the destruction of the first.
If an object is
initialized statically, the object is destroyed in the same order as if
the object was dynamically initialized. For an object of array or class
type, all subobjects of that object are destroyed before any block
variable with static storage duration initialized during the construction
of the subobjects is destroyed.
the object was dynamically initialized.
If the destruction of an object with static or thread storage duration
exits via an exception,
the function \tcode{std::terminate} is called\iref{except.terminate}.
\begin{example}
In the following program,
the elements of \tcode{a} are destroyed,
followed by \tocde{dt}, and
finally by the two \tcode{Btemp} objects:
\begin{codeblock}
struct DTemp { ~DTemp(); };
struct Temp {
~Temp() {
static DTemp dt;
}
};
struct BTemp {
~BTemp();
};
struct A {
const BTemp &tb;
~A();
};
A a[] = { (Temp(), BTemp()), BTemp() };

int main() {}
\end{codeblock}
If the array \tcode{a} were an object with automatic storage duration,
the \tcode{Btemp} temporaries would be destroyed
as each element of the array is destroyed\iref{class.temporary}.
\end{example}

\pnum
If a function contains a block variable of static or thread storage duration that has been
Expand All @@ -7542,12 +7608,13 @@
\pnum
\indextext{\idxcode{atexit}}%
\indexlibraryglobal{atexit}%
If the completion of the initialization of an object with static storage
If the deemed construction of a complete object with static storage
duration strongly happens before a call to \tcode{std::atexit}~(see
\libheader{cstdlib}, \ref{support.start.term}), the call to the function passed to
\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a
call to \tcode{std::atexit} strongly happens before the completion of the initialization of
an object with static storage duration, the call to the destructor for the
\tcode{std::atexit} is sequenced before the initiation of the destruction of the object.
If a call to \tcode{std::atexit} strongly happens before the deemed construction of
a complete object with static storage duration,
the completion of the destruction of the
object is sequenced before the call to the function passed to \tcode{std::atexit}. If a
call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the
call to the function passed to the second \tcode{std::atexit} call is sequenced before
Expand Down
8 changes: 5 additions & 3 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1704,7 +1704,8 @@
and no virtual base classes\iref{class.mi}, and

\item
the constructor selected to copy/move each direct base class subobject is trivial, and
the constructor selected to copy/move each direct base class subobject
is a direct member of that base class and is trivial, and

\item
for each non-static data member of
Expand Down Expand Up @@ -1986,7 +1987,7 @@
and no virtual base classes\iref{class.mi}, and

\item the assignment operator selected to copy/move each direct
base class subobject is trivial, and
base class subobject is a direct member of that base class and is trivial, and

\item
for each non-static data member of
Expand Down Expand Up @@ -3356,7 +3357,8 @@
\indextext{access control!anonymous \tcode{union}}%
\indextext{restriction!anonymous \tcode{union}}%
Each \grammarterm{member-declaration} in the \grammarterm{member-specification}
of an anonymous union shall either define one or more public non-static data members or
of an anonymous union shall define one or more public non-static data members,
be an \grammarterm{empty-declaration}, or
be a \grammarterm{static_assert-declaration}.
Nested types, anonymous unions, and functions
shall not be declared within an anonymous union.
Expand Down
45 changes: 45 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3041,6 +3041,33 @@
(for instance, via the C typedef in \libheaderref{stdbool.h})
is ill-formed in \Cpp{}.

\diffref{expr.unary.op}
\change
In certain contexts,
taking the address of a dereferenced null or past-the-end pointer value
is well-defined in C (and yields the original pointer value),
but results in undefined behavior in \Cpp{}.
\begin{example}
\begin{codeblock}
void f() {
char *p = nullptr;
char *p2 = &*p; // well-defined in C, undefined behavior in \Cpp{}
char *p3 = &p[0]; // well-defined in C, undefined behavior in \Cpp{}
int a[5];
int *q = &a[5]; // well-defined in C, undefined behavior in \Cpp{}
}
\end{codeblock}
\end{example}
\rationale
Consistent treatment of lvalues in \Cpp{}.
\effect
Well-formed and well-defined C code exhibits undefined behavior in \Cpp{}.
\difficulty
Syntactic transformation to pointer arithmetic
and possible addition of a check for null pointer values.
\howwide
Occasionally.

\diffref{expr.sizeof,expr.cast}
\change
In \Cpp{}, types can only be defined in declarations, not in expressions.\\
Expand Down Expand Up @@ -3165,6 +3192,24 @@

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

\diffref{dcl.pre}
\change
In \Cpp{}, no declaration of a variable can have \cv{} \tcode{void} type.
In C, this is allowed, unless the declaration is a definition.
\begin{example}
\begin{codeblock}
extern void x; // valid C, invalid in \Cpp{}
\end{codeblock}
\end{example}
\rationale
Stricter type checking in \Cpp{}.
\effect
Deletion of semantically well-defined feature.
\difficulty
Syntactic transformation.
\howwide
Seldom.

\diffref{dcl.stc}
\change
In \Cpp{}, the \keyword{static} or \keyword{extern} specifiers can only be applied to names of objects or functions.\\
Expand Down
Loading
Loading