![]() |
Integral const static member initialized inside a class
In the book C++ Primer(Fourth Edition) by Stanley Lippman, the
following is mentioned in page 471(Under the subsection "Intergral const static Members Are Special") "When a const static data member is initialized in the class body, the data member must still be defined outside the class definition." Here I understand that the data member should be of integral type. But I do not get compilation error even if I do not define the integral const static data member outside the class. Consider the following program named x.cpp: #include <cstdlib> #include <iostream> using namespace std; class Test { public: static int get(void); private: static const int x = 100; }; inline int Test::get(void) { return x; } int main() { cout << Test::get() << endl; return EXIT_SUCCESS; } Here note that Test::x is not defined outside the class definition. When I compile this program with g++ 3.4.3 g++ -std=c++98 -pedantic -Wall -Wextra x.cpp the program produces the following output when run: 100 Is it a bug in the compiler not to flag the missing definition of Test::x outside the class or what is mentioned in the 'C++ Primer' book is wrong ? Kindly clarify. (This question is for learning purpose only. Stroustrup has suggested the use of enum in such situations, in his book TC++PL Third Edition Page 249 - Section '10.4.6.2 Member Constants'. But he also mentions in this page that an initialized static integral constant member must still be uniquely defined somewhere and the initializer may not be repeated.) Thanks V.Subramanian |
Re: Integral const static member initialized inside a class
subramanian100in@yahoo.com, India wrote:
> #include <cstdlib> > #include <iostream> > > using namespace std; > > class Test > { > public: > static int get(void); > private: > static const int x = 100; > }; > > inline int Test::get(void) > { > return x; > } > ........ > Is it a bug in the compiler not to flag the missing definition of > Test::x outside the class or what is mentioned in the 'C++ Primer' > book is wrong ? Kindly clarify. I think that consts of simple types are actually never defined in memory,rather just hard coded, unless you take address of them. That's why you have to define it, but it is unused if you don;t need pointer. If that is not the case then you couldn't take address of such const. To be honest I never took address of such const ;) Greets |
Re: Integral const static member initialized inside a class
On 15 Jan., 16:32, subramanian wrote:
> In the book C++ Primer(Fourth Edition) by Stanley Lippman, the > following is mentioned in page 471(Under the subsection "Intergral > const static Members Are Special") > > "When a const static data member is initialized in the class body, the > data member must still be defined outside the class definition." > > Here I understand that the data member should be of integral type. But > I do not get compilation error even if I do not define the integral > const static data member outside the class. I think the author just wanted to make clear that even if an in-class initialization of a static const member is present, it is still only a declaration, not a definition. You "do not get compilation error" because the compiler is happy with declarations alone. If you really miss a definition for something that is needed the LINKER will complain about this (linker error, not compilation error). In this instance, only the value of this static const member is accessed. The compiler already knowns the value due to the initialization and the constness. It's a compile-time constant and doesn't require accessing the static object at runtime. If, however, you take the address of this member or use it as an argument for a function call that takes a reference-to-const you need to provide a definition for the member or else the LINKER will complain about undefined symbols. It's common practice in metaprogramming not to provide definitions for those compile-time constants. Cheers, SG |
Re: Integral const static member initialized inside a class
Quoting the standard 9.4.2 recital 4:
** 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 constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the programm and the namespace scope definition shall not contain an initializer. ** My interpretation is, that the following additional line is needed to be "standard compliant". Might be wrong. So g++ offers the service, that you can forget about the definition in namespace scope. .... class Test { public: static int get(void); private: static const int x = 100; }; //pay attation to that line const int Test::x; .... Yours sincerely, Eric |
Re: Integral const static member initialized inside a class
On Jan 15, 3:32 pm, "subramanian10...@yahoo.com, India"
<subramanian10...@yahoo.com> wrote: > In the book C++ Primer(Fourth Edition) by Stanley Lippman, the > following is mentioned in page 471(Under the subsection "Intergral > const static Members Are Special") > "When a const static data member is initialized in the class body, the > data member must still be defined outside the class definition." > Here I understand that the data member should be of integral type. But > I do not get compilation error even if I do not define the integral > const static data member outside the class. [...] > Here note that Test::x is not defined outside the class definition. > When I compile this program with g++ 3.4.3 > g++ -std=c++98 -pedantic -Wall -Wextra x.cpp > the program produces the following output when run: > 100 > Is it a bug in the compiler not to flag the missing definition of > Test::x outside the class or what is mentioned in the 'C++ Primer' > book is wrong ? Kindly clarify. In the general case, the lack of a definition is undefined behavior, so nothing the compiler does with it could be a bug. In the specific case of initialized static members of integral type, I think there are even special rules which say that the definition is not required if there is an immediate lvalue to rvalue conversion (which is the case in your code), so the code would be legal. (Try returning an int const&, instead of a value. That could make a difference.) In practice, whether I've remembered the standard correctly or not, no compiler will require a definition in the case of an immediate lvalue to rvalue conversion, and most won't require a definition if there is an lvalue to rvalue conversion in an inline function which takes a reference (e.g. something like std::vector<int>). -- James Kanze |
I've just stumbled into this issue. Stroustrup's book, mentioned by the OP, says: "If (and only if) you use an initialized member in a way that requires it to be stored as an object in memory, the member must be (uniquely) defined somewhere." It doesn't say what counts as that requirement. I have some code which compiles on MSVC (2008) but does not on GCC (tested with MingW 4.5.0). So evidently they disagree on what counts. My question is, who's correct? Here is the code:
Code:
class AThanks Andy |
| All times are GMT. The time now is 08:59 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.