Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Static const integral data members can be initialized?

Reply
Thread Tools

Static const integral data members can be initialized?

 
 
Immortal Nephi
Guest
Posts: n/a
 
      07-22-2010
Why do Microsoft C++ Compiler reports:

error C2864: 'obj::y' : only static const integral data members can be
initialized within a class

float and double keywords are not allowed to be in static const
inside class.

struct obj {
static const int x = 5; // OK
static const double y = 15.0; // c2864
};

int main() {
obj o;

return 0;
}
 
Reply With Quote
 
 
 
 
Öö Tiib
Guest
Posts: n/a
 
      07-22-2010
On 23 juuli, 00:42, Immortal Nephi <(E-Mail Removed)> wrote:
> * * * * Why do Microsoft C++ Compiler reports:
>
> error C2864: 'obj::y' : only static const integral data members can be
> initialized within a class
>
> * * * * float and double keywords are not allowed to be in static const inside class.


Not quite true. They can be static const inside a class but they can
not be initialized within class definition.

struct Obj
{
static double const y_;
};

double const Obj::y_ = 15.0;

int main()
{
Obj o;
return 0;
}
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      07-22-2010
On 07/23/10 09:42 AM, Immortal Nephi wrote:
> Why do Microsoft C++ Compiler reports:
>
> error C2864: 'obj::y' : only static const integral data members can be
> initialized within a class
>
> float and double keywords are not allowed to be in static const
> inside class.


float and double are not integral types.

Their representation my differ between the build host and the deployment
environment.

--
Ian Collins
 
Reply With Quote
 
TJorgenson
Guest
Posts: n/a
 
      07-22-2010
On Jul 22, 3:06*pm, Ian Collins <(E-Mail Removed)> wrote:
> On 07/23/10 09:42 AM, Immortal Nephi wrote:
>
> float and double are not integral types.
>
> Their representation my differ between the build host and the deployment
> environment.


And how exactly does initialization outside the class definition help
in this regard?

It seems to me that allowing initialization of static const float and
double within a class would not break anything and would be a useful
construct. I believe the problem you mention would be the same either
way.

Tony
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      07-22-2010
On 07/23/10 10:17 AM, TJorgenson wrote:
> On Jul 22, 3:06 pm, Ian Collins<(E-Mail Removed)> wrote:
>> On 07/23/10 09:42 AM, Immortal Nephi wrote:
>>
>> float and double are not integral types.
>>
>> Their representation my differ between the build host and the deployment
>> environment.

>
> And how exactly does initialization outside the class definition help
> in this regard?
>
> It seems to me that allowing initialization of static const float and
> double within a class would not break anything and would be a useful
> construct. I believe the problem you mention would be the same either
> way.


I'm sure a resident language lawyer can quote the chapter and verse, but
from a practical point of view, an initialisation within a class is a
compile time constant. The compiler can substitute the literal value as
an optimisation. Initialisations outside of the class are performed at
run time before main is called.

--
Ian Collins
 
Reply With Quote
 
TJorgenson
Guest
Posts: n/a
 
      07-22-2010
On Jul 22, 4:03*pm, Ian Collins <(E-Mail Removed)> wrote:
>
> I'm sure a resident language lawyer can quote the chapter and verse, but
> from a practical point of view, an initialisation within a class is a
> compile time constant. *The compiler can substitute the literal value as
> an optimisation. *Initialisations outside of the class are performed at
> run time before main is called.


So you are saying that the following class definition:

class D
{
static const double d;
};

with the following definition in a cpp file:

const double D::d = 0.1;

could cause the compiler to generate initialization code for this
constant that runs before main is called to generate the constant in
the format for the target processor that may be different from the
host that the compiler runs on. Agreed.

But if the compiler can generate this initialization code, I contend
that it could also generate the constant in the correct target format
as well. After all, the compiler needs to know the target processor
instruction set to generate the code. I still don't think this
justifies why floats and doubles can't be initialized within a class
definition.

Tony
 
Reply With Quote
 
TJorgenson
Guest
Posts: n/a
 
      07-23-2010
On Jul 22, 4:49*pm, Ian Collins <(E-Mail Removed)> wrote:

> >> I'm sure a resident language lawyer can quote the chapter and verse, but
> >> from a practical point of view, an initialisation within a class is a
> >> compile time constant. *The compiler can substitute the literal value as
> >> an optimisation. *Initialisations outside of the class are performed at
> >> run time before main is called.

>
> > So you are saying that the following class definition:

>
> > class D
> > {
> > * * *static const double d;
> > };

>
> > with the following definition in a cpp file:

>
> > const double D::d = 0.1;

>
> > could cause the compiler to generate initialization code for this
> > constant that runs before main is called to generate the constant in
> > the format for the target processor that may be different from the
> > host that the compiler runs on. Agreed.

>
> > But if the compiler can generate this initialization code, I contend
> > that it could also generate the constant in the correct target format
> > as well. After all, the compiler needs to know the target processor
> > instruction set to generate the code. I still don't think this
> > justifies why floats and doubles can't be initialized within a class
> > definition.

>
> But where do you stop? *If floating point values can be compile time
> constants, can they be used in switch cases? *As template parameters?


I get your point, but I'm not arguing for that. Switch cases with
floats would essentially require automatic generation of direct
equality comparisons, which could be problematic. I also understand
that allowing template parameters to be floats and doubles could cause
the generated code to have behavior that is processor/compiler/
compiler-option dependent. This would be bad IMO.

I just think initialization of all static constants could be allowed
within a class. I also think that the standard should not require that
constants that are initialized within a class also be defined outside
the class, unless the code explicitly takes the address of the
constant somewhere. I would expect a link error for that.

We have been getting away with not defining static const integers
outside the class in most cases even though it is strictly illegal,
but some constructs seem to generate code that requires the out-of-
class definition. For example, with our latest compiler using static
const integers in a conditional operator (? seems to require the out-
of-class definition if the constants are any integer types other that
int and unsigned int. This is a PITA IMO and it makes it hard for me
to sell my colleges on the idea that it is better to use static const
integers rather than #define. While it is true that this is
essentially just syntactic sugar after all, in this case it would make
it easier to sell a more C++ idiomatic solution for constants to those
looking to save keystrokes.

Tony
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      07-23-2010
On 07/23/10 12:21 PM, TJorgenson wrote:
> On Jul 22, 4:49 pm, Ian Collins<(E-Mail Removed)> wrote:
>
>>>> I'm sure a resident language lawyer can quote the chapter and verse, but
>>>> from a practical point of view, an initialisation within a class is a
>>>> compile time constant. The compiler can substitute the literal value as
>>>> an optimisation. Initialisations outside of the class are performed at
>>>> run time before main is called.

>>
>>> So you are saying that the following class definition:

>>
>>> class D
>>> {
>>> static const double d;
>>> };

>>
>>> with the following definition in a cpp file:

>>
>>> const double D::d = 0.1;

>>
>>> could cause the compiler to generate initialization code for this
>>> constant that runs before main is called to generate the constant in
>>> the format for the target processor that may be different from the
>>> host that the compiler runs on. Agreed.

>>
>>> But if the compiler can generate this initialization code, I contend
>>> that it could also generate the constant in the correct target format
>>> as well. After all, the compiler needs to know the target processor
>>> instruction set to generate the code. I still don't think this
>>> justifies why floats and doubles can't be initialized within a class
>>> definition.

>>
>> But where do you stop? If floating point values can be compile time
>> constants, can they be used in switch cases? As template parameters?

>
> I get your point, but I'm not arguing for that. Switch cases with
> floats would essentially require automatic generation of direct
> equality comparisons, which could be problematic. I also understand
> that allowing template parameters to be floats and doubles could cause
> the generated code to have behavior that is processor/compiler/
> compiler-option dependent. This would be bad IMO.
>
> I just think initialization of all static constants could be allowed
> within a class.


OK, consider how a compiler should evaluate

static const double d = 42.42*3.5/6;

> I also think that the standard should not require that
> constants that are initialized within a class also be defined outside
> the class, unless the code explicitly takes the address of the
> constant somewhere. I would expect a link error for that.


The wording of 9.4.2/4 is:

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 an integral constant expression (5.19). In
that case, the member can appear in integral constant expressions within
its scope. The member shall still be defined in a namespace scope if it
is used in the program and the namespace scope definition shall not
contain an initializer.

"used in the program" is is rather woolly.

> We have been getting away with not defining static const integers
> outside the class in most cases even though it is strictly illegal,
> but some constructs seem to generate code that requires the out-of-
> class definition. For example, with our latest compiler using static
> const integers in a conditional operator (? seems to require the out-
> of-class definition if the constants are any integer types other that
> int and unsigned int. This is a PITA IMO and it makes it hard for me
> to sell my colleges on the idea that it is better to use static const
> integers rather than #define.


If your colleagues (I assume you made a typo!) want to use #define, you
are in the wrong job!

--
Ian Collins
 
Reply With Quote
 
TJorgenson
Guest
Posts: n/a
 
      07-23-2010
On Jul 22, 5:40*pm, Ian Collins <(E-Mail Removed)> wrote:
>
> OK, consider how a compiler should evaluate
>
> * *static const double d = 42.42*3.5/6;
>

Ideally, the compiler should evaluate double constants the same way
the target environment will evaluate doubles, but this is still not
relevant to _where_ this constant expression lives (i.e. in the class
or outside).

> > I also think that the standard should not require that
> > constants that are initialized within a class also be defined outside
> > the class, unless the code explicitly takes the address of the
> > constant somewhere. I would expect a link error for that.

>
> The wording of 9.4.2/4 is:
>
> 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 an integral constant expression (5.19). In
> that case, the member can appear in integral constant expressions within
> its scope. The member shall still be defined in a namespace scope if it
> is used in the program and the namespace scope definition shall not
> contain an initializer.


Thanks for the reference.

> "used in the program" is is rather woolly.


I still think the standard could restrict "if it is used in the
program" to be "if its address is taken in the program". What other
"use in the program" (sic) should require a definition at namespace
scope?

I think it is rare to take the address of a static constant integer
and if you do so without providing the out-of-class definition you
will get a linker error that will be immediately fixed. The standard
language makes it the compiler writer’s job to decide when the out-of-
class definition is required, meaning that code may work now, but some
day somebody adds code that requires that definition and then we get
the linker error and have to explain why the definition wasn't
necessary before (even though it technically was).

Tony
 
Reply With Quote
 
Alf P. Steinbach /Usenet
Guest
Posts: n/a
 
      07-23-2010
* Ian Collins, on 23.07.2010 01:03:
> On 07/23/10 10:17 AM, TJorgenson wrote:
>> On Jul 22, 3:06 pm, Ian Collins<(E-Mail Removed)> wrote:
>>> On 07/23/10 09:42 AM, Immortal Nephi wrote:
>>>
>>> float and double are not integral types.
>>>
>>> Their representation my differ between the build host and the deployment
>>> environment.

>>
>> And how exactly does initialization outside the class definition help
>> in this regard?
>>
>> It seems to me that allowing initialization of static const float and
>> double within a class would not break anything and would be a useful
>> construct. I believe the problem you mention would be the same either
>> way.

>
> I'm sure a resident language lawyer can quote the chapter and verse, but
> from a practical point of view, an initialisation within a class is a
> compile time constant. The compiler can substitute the literal value as
> an optimisation. Initialisations outside of the class are performed at
> run time before main is called.


Well, I'm not a language lawyer, but I'm good at common sense.

One can easily obtain the same effect as initialization within the class
definition, e.g., for the OP's code, off the cuff,

template< class Dummy >
struct obj_constants
{
static int const x;
static double const y;
};

template< class Dummy >
int const obj_constants< Dummy >: = 5;

template< class Dummy >
int const obj_constants< Dummy >::y = 15.0;

struct obj
public obj_constants< void >
{
// Whatever more.
};

Hence any argument based on this generating wrong code is invalid.

As I recall the problem with initializations-in-class was just the vicarious can
of worms argument that you mention later down-thread,

"But where do you stop? If floating point values can be compile time
constants, can they be used in switch cases? As template parameters?"

i.e. political.

No, you're not allowed to build an annex, because where would it stop? Next we'd
have to allow you to build a busy airport, to great annoyance to your
neighbours. Also, you can't take up painting as a profession, because if we
allowed that and everybody chose to be painters, then nobody would produce food
for the world and we'd all starve to death. And so on. Where would it stop?


Cheers & hth.,

- Alf

--
blog at <url: http://alfps.wordpress.com>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" Adem C++ 42 11-04-2008 12:39 PM
C/C++ language proposal: Change the 'case expression' from "integral constant-expression" to "integral expression" Adem C Programming 45 11-04-2008 12:39 PM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
error Message: "only const static integral data members can be initializedinside a class or struct" Susan Baker C++ 2 07-03-2005 12:29 PM
About static const members appearing in another static const definitions Rakesh Sinha C++ 4 01-13-2005 08:11 AM



Advertisments