Skip to content

Commit fc62fb5

Browse files
burblebeetkoeppe
authored andcommitted
CWG2879 Undesired outcomes with const_cast
Also fixes CWG1965.
1 parent b6c37b1 commit fc62fb5

File tree

2 files changed

+28
-25
lines changed

2 files changed

+28
-25
lines changed

source/declarations.tex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5810,6 +5810,10 @@
58105810
return x;
58115811
}
58125812
constexpr int z = f(); // error: not a constant expression
5813+
5814+
typedef int *A[3]; // array of 3 pointer to \tcode{int}
5815+
typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int}
5816+
ACPC &&r = AP{}; // binds directly
58135817
\end{codeblock}
58145818
\end{example}
58155819

source/expressions.tex

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@
266266
\end{note}
267267

268268
\pnum
269-
Whenever a prvalue appears as an operand of an operator that
269+
Unless otherwise specified\iref{expr.const.cast},
270+
whenever a prvalue appears as an operand of an operator that
270271
expects a glvalue for that operand, the
271272
temporary materialization conversion\iref{conv.rval} is
272273
applied to convert the expression to an xvalue.
@@ -4497,7 +4498,10 @@
44974498
otherwise, the result is a prvalue and the
44984499
lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array},
44994500
and function-to-pointer\iref{conv.func} standard conversions are
4500-
performed on the expression \tcode{v}. Conversions that can be performed explicitly using
4501+
performed on the expression \tcode{v}.
4502+
The temporary materialization conversion\iref{conv.rval} is not
4503+
performed on \tcode{v}, other than as specified below.
4504+
Conversions that can be performed explicitly using
45014505
\keyword{const_cast} are listed below. No other conversion shall be
45024506
performed explicitly using \keyword{const_cast}.
45034507

@@ -4508,23 +4512,16 @@
45084512
\end{note}
45094513

45104514
\pnum
4511-
For two similar types \tcode{T1} and \tcode{T2}\iref{conv.qual},
4512-
a prvalue of type \tcode{T1} may be explicitly
4515+
For two similar object pointer or pointer to data member types
4516+
\tcode{T1} and \tcode{T2}\iref{conv.qual},
4517+
a prvalue of type \tcode{T1} can be explicitly
45134518
converted to the type \tcode{T2} using a \keyword{const_cast}
45144519
if, considering the qualification-decompositions of both types,
45154520
each $P^1_i$ is the same as $P^2_i$ for all $i$.
4516-
The result of a \keyword{const_cast} refers to the original entity.
4517-
\begin{example}
4518-
\begin{codeblock}
4519-
typedef int *A[3]; // array of 3 pointer to \tcode{int}
4520-
typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int}
4521-
4522-
CA &&r = A{}; // OK, reference binds to temporary array object
4523-
// after qualification conversion to type \tcode{CA}
4524-
A &&r1 = const_cast<A>(CA{}); // error: temporary array decayed to pointer
4525-
A &&r2 = const_cast<A&&>(CA{}); // OK
4526-
\end{codeblock}
4527-
\end{example}
4521+
If \tcode{v} is a null pointer or null member pointer,
4522+
the result is a null pointer or null member pointer, respectively.
4523+
Otherwise, the result points to or past the end of the same object, or
4524+
points to the same member, respectively, as \tcode{v}.
45284525

45294526
\pnum
45304527
For two object types \tcode{T1} and \tcode{T2}, if a pointer to \tcode{T1} can
@@ -4537,20 +4534,22 @@
45374534
\item a glvalue of type \tcode{T1} can be explicitly converted to an xvalue
45384535
of type \tcode{T2} using the cast \tcode{\keyword{const_cast}<T2\&\&>}; and
45394536

4540-
\item if \tcode{T1} is a class type, a prvalue of type \tcode{T1} can be
4537+
\item if \tcode{T1} is a class or array type,
4538+
a prvalue of type \tcode{T1} can be
45414539
explicitly converted to an xvalue of type \tcode{T2} using the cast
45424540
\tcode{\keyword{const_cast}<T2\&\&>}.
4541+
The temporary materialization conversion is performed on \tcode{v}.
45434542
\end{itemize}
45444543

4545-
The result of a reference \keyword{const_cast} refers
4546-
to the original object if the operand is a glvalue and
4547-
to the result of applying the temporary materialization conversion\iref{conv.rval} otherwise.
4544+
The result refers to the same object as the (possibly converted) operand.
4545+
\begin{example}
4546+
\begin{codeblock}
4547+
typedef int *A[3]; // array of 3 pointer to \tcode{int}
4548+
typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int}
45484549

4549-
\pnum
4550-
A null pointer value\iref{basic.compound} is converted to the null pointer
4551-
value of the destination type. The null member pointer
4552-
value\iref{conv.mem} is converted to the null member pointer value of
4553-
the destination type.
4550+
auto &&r2 = const_cast<A&&>(CA{}); // OK, temporary materialization conversion is performed
4551+
\end{codeblock}
4552+
\end{example}
45544553

45554554
\pnum
45564555
\begin{note}

0 commit comments

Comments
 (0)