Topic: Defect Report: definition of static const data members


Author: gennaro_prota@yahoo.com (Gennaro Prota)
Date: Sat, 24 Jan 2004 18:56:17 +0000 (UTC)
Raw View
On Fri, 23 Jan 2004 06:12:11 +0000 (UTC), dave@boost-consulting.com
(David Abrahams) wrote:

>gennaro_prota@yahoo.com (Gennaro Prota) writes:
>
>> On Wed, 21 Jan 2004 17:57:32 +0000 (UTC), dave@boost-consulting.com
>> (David Abrahams) wrote:
>>
>>>Did you look carefully to make sure there's not already a DR on
>>>this?  I'm pretty sure that there is one.
>>
>> Which one? I've checked again now but I can't see any.
>
>I admit it's hard to find but I think this one applies:
>
>http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#48


Well, yes. But my DR starts exactly with: "As a result of the
resolution of core issue 48" :)

The problem is that the issue was settled in a way that solves much
less than it was supposed to solve; that's why I decided to file, so
to speak, a DR on a DR.

I understand this may seem a little 'audacious' on my part, but please
keep reading. Quoting from the text of DR 48 (emphasis mine):

 "Originally, all static data members still had to be defined
  outside the class whether they were used or not.

  But that restriction was supposed to be lifted [...]

  In particular, if an integral/enum const static data member is
  initialized within the class, ** and its address is never taken **,
  we agreed that no namespace-scope definition was required."


The corresponding resolution doesn't reflect this intent, with the
definition being still required in most situations anyway: it's enough
that the constant appears outside a place where constants are
*required* (ignoring the obvious cases of sizeof and typeid) and you
have to provide a definition. For instance:

  struct X {
   static const int c =3D 1;
  };

  void f(int n)
  {
   if (n =3D=3D X::c)   // <-- potentially evaluated
    ...
  }



<start digression>

Most usages of non-enum BOOST_STATIC_COSTANTs, for instance, are (or
were, last time I checked) non-conforming. If you recall, Paul
Mensonides pointed out that the following template


  // map_integral
=A0
  template<class T, T V> struct map_integral : identity<T> {
=A0=A0=A0 static const T value =3D V;
  };
=A0
  template<class T, T V> const T map_integral<T, V>::value;


whose main goal is to map the same couples (type, value) to the same
storage, also solves the definition problem. In this usage it is an
excellent hack (if your compiler is good enough), but IMHO still a
hack on a language defect.


<end digression>


What I propose is to solve the issue according to the original intent,
which is also what users expect and all compilers that I know of
already do. Or, in practice, we would have a rule that exists only as
words in a standard document.

PS: I've sent a copy of this to Mr. Adamczyk to clarify an important
doubt that occurred to me while writing this reply:

if no definition is provided for an integral static const data member
is that member an object? Paragraph 1.8/1 seems to say no, and in fact
it's difficult to think it is an object without assuming/pretending
that a region of storage exists for it (an object *is* a region of
storage according to the standard).

I would think that when no definition is required we have to assume
that it could be a non-object. In that case there's nothing in 3.2
which says what 'used' means for such an entity and the current
wording would thus be defective. Also, since the name of the member is
an lvalue and 3.10/2 says an lvalue refers to an object we would have
another problem.

OTOH the standard could pretend it is always an object (though the
compiler can optimize it away) and in this case it should probably
make a special case for it in 3.2/2.


Thoughts?


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: Gennaro Prota <gennaro_prota@yahoo.com>
Date: Tue, 20 Jan 2004 19:56:29 +0000 (UTC)
Raw View
[Note: Forwarded to C++ Commitee -sdc ]

As a result of the resolution of core issue 48, the current C++
standard is not in sync with existing practice and with user
expectations as far as definitions of static data members having const
integral or const enumeration type are concerned. Basically what
current implementations do is to require a definition only if the
address of the constant is taken. Example:

void f() {

  std::string s;
  ...

  // current implementations don't require a definition
  if (s.find('a', 3) == std::string::npos) {
   ...
  }

To the letter of the standard, though, the above requires a definition
of npos, since the expression std::string::npos is potentially
evaluated. I think this problem would be easily solved with simple
changes to 9.4.2 [class.static.data] /4, 9.4.2 [class.static.data] /5
and 3.2 [basic.def.odr] /3.


Proposed resolution:

Replace 9.4.2 [class.static.data] paragraph 4 with:

"If a static data member is of const integral or const enumeration
type, its declaration in the class definition can specify a
constant-initializer which shall be [note1] an integral constant
expression (5.19). In that case, the member can appear in integral
constant expressions. No definition of the member is required, unless
an lvalue expression that designates it is potentially evaluated and
either used as operand to the built-in unary & operator [note 2] or
directly bound to a reference.

If a definition exists, it shall be at namespace scope and shall not
contain an initializer."

In 9.4.2 [class.static.data] paragraph 5 change

"There shall be exactly one definition of a static data member that is
used in a program; no diagnostic is required; see 3.2."

 to

"Except as allowed by 9.4.2 par. 4, there shall be exactly one
definition of a static data member that is potentially evaluated (3.2)
in a program; no diagnostic is required."


In 3.2 [basic.def.odr] paragraph 3 add, at the beginning:

"Except for the omission allowed by 9.4.2, par. 4,"


-----------------------------------------
[note 1] Actually it shall be a "= followed by a constant-expression".
This could probably be an editorial fix, rather than a separate DR.


[note 2] Note that this is the case when reinterpret_cast-ing to a
reference, like in
struct X { static const int value = 0; };
const char & c = reinterpret_cast<const char&>(X::value);

See 5.2.10/10



Genny.



[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Wed, 21 Jan 2004 17:57:32 +0000 (UTC)
Raw View
Gennaro Prota <gennaro_prota@yahoo.com> writes:

> [Note: Forwarded to C++ Commitee -sdc ]
>
> As a result of the resolution of core issue 48, the current C++
> standard is not in sync with existing practice and with user
> expectations as far as definitions of static data members having const
> integral or const enumeration type are concerned. Basically what
> current implementations do is to require a definition only if the
> address of the constant is taken.

Did you look carefully to make sure there's not already a DR on
this?  I'm pretty sure that there is one.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gennaro_prota@yahoo.com (Gennaro Prota)
Date: Thu, 22 Jan 2004 02:22:01 +0000 (UTC)
Raw View
On Wed, 21 Jan 2004 17:57:32 +0000 (UTC), dave@boost-consulting.com
(David Abrahams) wrote:

>Did you look carefully to make sure there's not already a DR on
>this?  I'm pretty sure that there is one.

Which one? I've checked again now but I can't see any.


Genny.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dave@boost-consulting.com (David Abrahams)
Date: Fri, 23 Jan 2004 06:12:11 +0000 (UTC)
Raw View
gennaro_prota@yahoo.com (Gennaro Prota) writes:

> On Wed, 21 Jan 2004 17:57:32 +0000 (UTC), dave@boost-consulting.com
> (David Abrahams) wrote:
>
>>Did you look carefully to make sure there's not already a DR on
>>this?  I'm pretty sure that there is one.
>
> Which one? I've checked again now but I can't see any.

I admit it's hard to find but I think this one applies:

http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/cwg_defects.html#48

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]