<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    CWG Issue 94</TITLE>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  @media (prefers-color-scheme: dark) {
    HTML { background-color:#202020; color:#f0f0f0; }
    A { color:#5bc0ff; }
    A:visited { color:#c6a8ff; }
    A:hover, a:focus { color:#afd7ff; }
    INS { background-color:#033a16; color:#aff5b4; }
    .INS { background-color: #033a16; }
    DEL { background-color:#67060c; color:#ffdcd7; }
    .DEL { background-color:#67060c; }
  }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<P><EM>This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21
  Core Issues List revision 118b.
  See http://www.open-std.org/jtc1/sc22/wg21/ for the official
  list.</EM></P>
<P>2025-09-28</P>
<HR>
<A NAME="94"></A><H4>94.
  
Inconsistencies in the descriptions of constant expressions
</H4>
<B>Section: </B>7.7&#160; [<A href="https://wg21.link/expr.const">expr.const</A>]
 &#160;&#160;&#160;

 <B>Status: </B>TC1
 &#160;&#160;&#160;

 <B>Submitter: </B>Mike Miller
 &#160;&#160;&#160;

 <B>Date: </B>8 Feb 1999<BR>





<OL>
<LI>
According to
11.4.9.3 [<A href="https://wg21.link/class.static.data#4">class.static.data</A>] paragraph 4,
 a static const integral or const enumeration data member initialized
with an integral constant expression "can appear in integral constant expressions
<INS>within its scope</INS>" [emphasis mine]. This means that the following
is not permitted:

<PRE>
    struct S {
        static const int c = 5;
    };
    int a[S::c];    // error: S::c not in scope
</PRE>
Is this restriction intentional? If so, what was the rationale for the
restriction?

<P>
<U>Bjarne Stroustrup</U>: I think that once you have said <TT>S::</TT>,
<TT>c</TT> is in scope so that</P>
<PRE>
    int a[S::c];
</PRE>
is ok.

<P>
<U>Mike Miller</U>: I'd like to think that's what it meant, but I
don't believe that's what it said. According to
6.4 [<A href="https://wg21.link/basic.scope#1">basic.scope</A>] paragraph 1,
 the scope of
a name is the region "in which that name may be used as an unqualified
name." You can, indeed, use a qualified name to refer to a name that
is not in scope, but that only goes to reinforce my point that
"<TT>S::c</TT>" is not in scope at the point where the expression
containing it is used. I think the phrase "within its scope" is at
best misleading and should be removed. (Unless there's a reason I'm
missing for restricting the use of static member constants to their
scope.)</P>
</LI>
<LI>
According to 7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]
paragraph
1, integral constant expressions can "involve...const variables or static
data members of integral or enumeration types initialized with constant
expressions." However, in 7.7 [<A href="https://wg21.link/expr.const#3">expr.const</A>] paragraph 3,
 arithmetic constant expressions cannot include them. This
seems a rather gratuitous distinction and one likely to bite programmers
trained always to use const variables instead of preprocessor definitions.
Again, is there a rationale for the difference?

<P>As far as I can tell from 7.7 [<A href="https://wg21.link/expr.const#2">expr.const</A>] paragraph 2,
 "arithmetic constant expressions" (as distinct from "integral
constant expressions") are used only in static initializers to distinguish
between static and dynamic initialization. They include floating point
types and exclude non-type template parameters, as well as the const variables
and static data members.</P>
<LI>
<P>There is a minor error in 7.7 [<A href="https://wg21.link/expr.const#2">expr.const</A>] paragraph 2.
 The first sentence says, "Other expressions are considered
constant expressions only for the purpose of non-local static object initialization."
However, 8.10 [<A href="https://wg21.link/stmt.dcl#4">stmt.dcl</A>] paragraph 4
appears
to rely on the same definition dealing with the initialization of local
static objects. I think that the words "non-local" should be dropped and
a cross reference to 8.10 [<A href="https://wg21.link/stmt.dcl">stmt.dcl</A>]
added.</P>
</LI>
<LI>
7.7 [<A href="https://wg21.link/expr.const#4">expr.const</A>] paragraph 4
says, "An expression
that designates the address of a member or base class of a non-POD class
object (clause 9) is not an address constant expression (11.9.5 [<A href="https://wg21.link/class.cdtor">class.cdtor</A>]
)."

<P>I'm guessing that should be "non-static member," like the similar
prohibition in 11.9.5 [<A href="https://wg21.link/class.cdtor">class.cdtor</A>]
 regarding
out-of-lifetime access to members of non-POD class objects.</P>
</LI>
</LI>
</OL>

<P><B>Proposed resolutions (10/00):</B></P>

<OL>
<LI><P>Remove the phrase "within its scope" in
11.4.9.3 [<A href="https://wg21.link/class.static.data#4">class.static.data</A>] paragraph 4.
</P></LI>
<LI>

Replace 7.7 [<A href="https://wg21.link/expr.const#3">expr.const</A>] paragraph 3 with the following:

<BLOCKQUOTE>

An <I>arithmetic constant expression</I> shall satisfy the
requirements for an integral constant expression, except that

<UL>
<LI>floating literals need not be cast to integral or enumeration
type, and</LI>
<LI>conversions to floating point types are permitted.</LI>
</UL>

</BLOCKQUOTE>
</LI>
<LI><P>This is not a defect; no change is required.  The suggested
wording would be more accurate, but since the effect on local
initialization is unobservable the current wording is adequate.</P></LI>

<LI><P>Change the referenced sentence in 7.7 [<A href="https://wg21.link/expr.const#4">expr.const</A>] paragraph 4
to "An expression that designates the address of a
subobject of a non-POD class object is not an address constant
expression."</P></LI>
</OL>
<BR><BR>
</BODY>
</HTML>
