Re: Static const integral data members can be initialized?
On Jul 23, 1:40 am, Ian Collins <ian-n...@hotmail.com> wrote:
On 07/23/10 12:21 PM, TJorgenson wrote:
On Jul 22, 4:49 pm, Ian Collins<ian-n...@hotmail.com> 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;
The same way it would if this were a variable at namespace
scope.
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:
The wording in the draft of C++0x has changed considerably. It
allows the initializer for all "literal types". All scalar
types are literal types, as are some class types, so you can
write things like:
class POD { int a; int b; };
class Toto
{
static double const d = 3.14159;
static POD const c = { 42, -1 };
// ...
};
(if I've understood correctly), and an expression like Toto::c.a
would be an integral constant expression.
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.
=A73.2/2:
An expression is potentially evaluated unless is the
operand of the sizeof operator (5.3.3), or is the
operand of the typeid operator and does not designate
an lvalue of polymorphic class type (5.2.8). An object
or non-overloaded function is used if its name appears
in a potentially-evaluated expression. [...]
The last "used" is in italics, so this is a definition of the
term. (The text goes on to define what used means for other
things, like virtual functions, etc.)
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!
Or rather his colleagues are in the wrong job.
--
James Kanze