Let say that I have two different versions of the same header foo.hpp
, the first one:
// File foo.hpp
#ifndef FILE_FOO
#define FILE_FOO
namespace X
{
static const int i = 13;
static const double d = 17.0;
}
#endif
and the second one:
// File foo.hpp
#ifndef FILE_FOO
#define FILE_FOO
struct X
{
static const int i = 13;
static const double d = 17.0;
};
#endif
In the latter case the use of a structure is pointless, but I have done it on purpose to highlight my question. In both cases I have tried to build the following source file foo.cpp
:
// File foo.cpp
#include "foo.hpp"
#include <iostream>
int main()
{
std::cout << X::i << std::endl;
std::cout << X::d << std::endl;
return 0;
}
but only in the latter I get the following error:
In file included from foo.cpp:2:
foo.hpp:7: error: floating-point literal cannot appear in a constant-expression
foo.hpp:7: error: ISO C++ forbids initialization of member constant ‘d’ of non-integral type ‘const double’
I am using g++
4.2.1 (so still with C++98 standard) and -pedantic
, this option is strictly required to get the above error.
As discussed here, I can see the point of allowing only static constant integral or enumeration types to be initialized inside the class, because I guess the C++ standard does not specify how floating point should be implemented at compile time and it leaves it to the processor. But at this point the namespace case is misleading me...
Finally, the questions:
- How does the compiler behave and translate the source into the object code in the above two cases?
- Why does it give an error only with the second version of the header?
Thanks for your help!