By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
448,652 Members | 1,697 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 448,652 IT Pros & Developers. It's quick & easy.

Integral type for static class variables

P: n/a
Hi,
Why is there a restriction that only integral types can be made static
constant members of a class?

For e.g.,

class B {
private:
static const double K = 10;
};

MSVC++ 2005 gave me an error, but gcc 3.4.4 is compiling it straight.
It is mentioned in Item 2 of
Effective C++, 3rd Edition too.

Thanks
Sep 4 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Ranganath wrote:
Why is there a restriction that only integral types can be made static
constant members of a class?
You can make any type a static constant member of a class. You just
can't initialise it right there and then if it's not an integral type.
>
For e.g.,

class B {
private:
static const double K = 10;
};

MSVC++ 2005 gave me an error, but gcc 3.4.4 is compiling it straight.
"Straight"? Are you telling your compiler to actually compile C++ or do
you allow it to use all extensions it can possibly use?
It is mentioned in Item 2 of
Effective C++, 3rd Edition too.
I am not sure why such limitation was introduced, but I know that there
were times when _no_ object could be initialised like that, inside the
class definition. You would need to always define it outside and then
initialise in that definition. The integral static constant members
were allowed to be initialised so that they can be used to form integral
constant expressions where needed (like array sizes). Integral constant
expressions are a special case, there are no non-integral constant
expressions; all others are not truly compile-time constants. Even
double values can be different during run-time depending on the
availability of the hardware or its settings, AIUI. Since there are no
true compile-time constants of any other types except integral ones,
there is no sense to allow initialising those in the class definition,
since you're not going to be able to use them as true constants anyway.

Those are my guesses, of course.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 4 '08 #2

P: n/a
On Sep 4, 7:59 pm, Victor Bazarov <v.Abaza...@comAcast.netwrote:
Ranganath wrote:
Why is there a restriction that only integral types can be
made static constant members of a class?
You can make any type a static constant member of a class.
You just can't initialise it right there and then if it's not
an integral type.
For e.g.,
class B {
private:
static const double K = 10;
};
MSVC++ 2005 gave me an error, but gcc 3.4.4 is compiling it straight.
"Straight"? Are you telling your compiler to actually compile
C++ or do you allow it to use all extensions it can possibly
use?
Such an initialization will be allowed in C++0x; it's possible
that g++ is jumping the gun, and already supporting it. (If the
code compiled with g++ -std=c++98 -pedantic, I'd consider it a
bug. But it doesn't, at least not with g++ 4.1.0.)
It is mentioned in Item 2 of
Effective C++, 3rd Edition too.
I am not sure why such limitation was introduced, but I know
that there were times when _no_ object could be initialised
like that, inside the class definition.
Exactly. No such limitation was ever introduced. From the
beginning, only a definition could have an initializer, and the
declaration of a static data member in a class definition is
*not* a definition. (Back in the old days, implementing it as
such would have created significant implementation difficulties
for compilers.) The standard technique when one needed a
"constant integral expression" which was a member was to use an
enum (and there are no contexts in the language where you need a
"constant expression" which is not a "constant integral
expression"). The enum was felt to be a hack, and didn't have
the right type (which became very significant with introduction
of templates), so toward the end of the original standardization
procedure, the committee created a special exception to allow
initialization expressions for static const members of integral
type, provided the initialization expression was itself a
constant integral expression. (A "hack" in the language to
allow you to avoid a hack in your code:-).) As it was late in
the standardization procedure, the committee doubtlessly wanted
to make the minimum change necessary (thus avoiding any risk),
and didn't have time to analyse possible consequences of a more
extensive change. Since then, of course, we have more actual
experience, and the committee has had time to work out all
possible consequences in detail.
You would need to always define it outside and then initialise
in that definition. The integral static constant members were
allowed to be initialised so that they can be used to form
integral constant expressions where needed (like array sizes).
Integral constant expressions are a special case, there are no
non-integral constant expressions; all others are not truly
compile-time constants.
That's not quite true; there is a concept of "constant
expression" which is not an "integral constant expression".
It's more limited than an integral constant expression, however,
and is only relevant when used to initialize variables at
namespace scope (where it implies static initialization rather
than dynamic).
Even double values can be different during run-time depending
on the availability of the hardware or its settings, AIUI.
I think that's true (although I don't know a platform where it
is the case). On the other hand, given:

extern double f() ;
double d1 = f() ;
double d2 = 2.0 * 3.14159 ;

, the compiler must ensure that d2 is initialized before d1 (and
thus, that if f() uses d2, it sees 3.14159, and not 0.0).
Since there are no true compile-time constants of any other
types except integral ones, there is no sense to allow
initialising those in the class definition, since you're not
going to be able to use them as true constants anyway.
You still won't be able to use them as constants, even in C++0x,
unless you explicitly declare it constexpr. (At least, that's
how I understand the current draft.)

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 5 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.