Topic: Initializing data members in C++0x


Author: Scott Meyers <smeyers@aristeia.com>
Date: Tue, 19 May 2009 11:59:18 CST
Raw View
My understanding is that C++0x allows non-static data members of any
type to be given a default initialization value, e.g.,

 class Widget {
   double fudgeFactor = 1.5;       // default init. value for non-static double
 };

My reading of 9.4.2 in N2800 is that the corresponding syntax for
static data members is invalid, because such initialization is allowed
only for const statics initialized with integral constant expressions.
 So this appears to be okay,

 class Widget {
   static const double d = 1;         // initializer is integral
 };

but this does not:

 class Widget {
   static const double d = 1.5;       // initializer is not integral
 };

This makes no sense to me.  I don't understand why only const statics
can have their initial values specified within a class definition, and
I don't understand why only integral constant expressions may be used
as in-class initializers for static data members.  I do understand
that there have to be some restrictions imposed in cases where a
static data member is used as a integral constant expression, but if
no such use is made, why isn't the following valid?

 class Widget {
   static double fudgeFactor = 1.5;    // init. value for static double
 };

Thanks,

Scott


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: daniel.kruegler@googlemail.com
Date: Tue, 19 May 2009 21:46:37 CST
Raw View
On 19 Mai, 19:59, Scott Meyers <smey...@aristeia.com> wrote:
> My understanding is that C++0x allows non-static data members of any
> type to be given a default initialization value, e.g.,
>
>  class Widget {
>    double fudgeFactor = 1.5;       // default init. value for non-static double
>  };
>
> My reading of 9.4.2 in N2800 is that the corresponding syntax for
> static data members is invalid, because such initialization is allowed
> only for const statics initialized with integral constant expressions.
>  So this appears to be okay,
>
>  class Widget {
>    static const double d = 1;         // initializer is integral
>  };
>
> but this does not:
>
>  class Widget {
>    static const double d = 1.5;       // initializer is not integral
>  };
>
> This makes no sense to me.  I don't understand why only const statics
> can have their initial values specified within a class definition, and
> I don't understand why only integral constant expressions may be used
> as in-class initializers for static data members.  I do understand
> that there have to be some restrictions imposed in cases where a
> static data member is used as a integral constant expression, but if
> no such use is made, why isn't the following valid?
>
>  class Widget {
>    static double fudgeFactor = 1.5;    // init. value for static double
>  };

This inconsistence is just in the process to becoming fixed, see

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#714

To summarize: If accepted the resolution will ensure that
the only requirement for a static data member in-class
initializer is a /constant expression/ per definition of 5.19
[expr.const].

HTH & Greetings from Bremen,

Daniel Kr   gler



--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Anthony Williams <anthony.ajw@gmail.com>
Date: Tue, 19 May 2009 21:46:48 CST
Raw View
Scott Meyers <smeyers@aristeia.com> writes:

> My understanding is that C++0x allows non-static data members of any
> type to be given a default initialization value, e.g.,
>
>  class Widget {
>    double fudgeFactor = 1.5;       // default init. value for non-static double
>  };
>
> My reading of 9.4.2 in N2800 is that the corresponding syntax for
> static data members is invalid, because such initialization is allowed
> only for const statics initialized with integral constant expressions.

This looks like an unintentional omission. 9.4.2 talks about
initialization of effective literal types, and use of constexpr. This
seems to indicate to me that initialization with any constant expression
should be OK, as per the usual constexpr initialization rules.

Just checked --- this is issue 714, which is marked as "ready":

http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#714

Anthony
--
Author of C++ Concurrency in Action | http://www.manning.com/williams
just::thread C++0x thread library   | http://www.stdthread.co.uk
Just Software Solutions Ltd         | http://www.justsoftwaresolutions.co.uk
15 Carrallack Mews, St Just, Cornwall, TR19 7UL, UK. Company No. 5478976

[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Scott Meyers <usenet@aristeia.com>
Date: Wed, 20 May 2009 17:14:10 CST
Raw View
daniel.kruegler@googlemail.com wrote:
> To summarize: If accepted the resolution will ensure that
> the only requirement for a static data member in-class
> initializer is a /constant expression/ per definition of 5.19
> [expr.const].

I see that in the revised wording, but it still looks to me like the static
itself must be either const or constexpr.  I believe the following
should be valid:

class Widget {
    static double fudgeFactor = 1.5;
};

Am I misreading the text in the resolution of issue 714?

Thanks,

Scott

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: daniel.kruegler@googlemail.com
Date: Thu, 21 May 2009 10:32:37 CST
Raw View
On 21 Mai, 01:14, Scott Meyers <use...@aristeia.com> wrote:
> daniel.krueg...@googlemail.com wrote:
> > To summarize: If accepted the resolution will ensure that
> > the only requirement for a static data member in-class
> > initializer is a /constant expression/ per definition of 5.19
> > [expr.const].
>
> I see that in the revised wording, but it still looks to me like the static
> itself must be either const or constexpr.  I believe the following
> should be valid:
>
> class Widget {
>     static double fudgeFactor = 1.5;
>
> };
>
> Am I misreading the text in the resolution of issue 714?

I don't think so. My first reaction to your remaining question
was to argue that there is much lesser advantage for
non-const(expr) static data members. The One-definition
rules, most specifically [basic.def.odr]/2

"[..] An object or non-overloaded function whose name appears
as a potentially-evaluated expression is used unless it is an
object that satisfies the requirements for appearing in a constant
expression (5.19) and the lvalue-to-rvalue conversion (4.1) is
immediately applied. [..]"

makes an actual definition of the "const static" unnecessary,
if only used in constant expressions. This is not the case for
non-const statics.

Now after some settling I certainly agree that providing such
an explicit definition is usually necessary anyway, because
it's sufficient to take such an lvalue of - let's say - type T as
argument to any function accepting a reference to const T,
to add the need for such a definition. So I indeed agree that
it would make sense to allow an in-class initializer for static
data members in all cases where the initializer expression
is a /constant expression/. It seems that relevant parts of
the standard already ensure that both the initializer *and*
the data type of the initialization target are correct for further
special handling as in [basic.def.odr]/5 b2, in [expr.const]/2
b5+6, or in [dcl.type.cv]/2.

Greetings from Bremen,

Daniel

--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]