432,474 Members | 966 Online
Need help? Post your question and get tips & solutions from a community of 432,474 IT Pros & Developers. It's quick & easy.

# When is a static data member defined?

 P: n/a In the following code, at what point is S::c fully defined? #include using std::cout; using std::endl; using std::ostream; class C { int _v; public: C(const int& v) :_v(v) {} ostream& print(ostream& out) const { return out << _v; } }; struct S { static const C c; }; const C S::c = C(42); ostream& operator<<(ostream& out, const S& s) { s.c.print(out); return out; } int main() { S s; cout << s << endl; return 0; } -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #1
24 Replies

 P: n/a Steven T. Hatton wrote: In the following code, at what point is S::c fully defined? #include [...] const C S::c = C(42); Here. [...] int main() { S s; cout << s << endl; return 0; } V Jul 22 '05 #2

 P: n/a Steven T. Hatton wrote: In the following code, at what point is S::c fully defined? #include using std::cout; using std::endl; using std::ostream; class C { int _v; public: C(const int& v) :_v(v) {} ostream& print(ostream& out) const { return out << _v; } }; struct S { static const C c; }; const C S::c = C(42); Here. -- Ioannis Vranos http://www23.brinkster.com/noicys Jul 22 '05 #3

 P: n/a Victor Bazarov wrote: Steven T. Hatton wrote: In the following code, at what point is S::c fully defined? #include [...] const C S::c = C(42); Here. I agree. At what point is the memory (typically) allocated? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #4

 P: n/a Steven T. Hatton wrote: I agree. At what point is the memory (typically) allocated? S::c is statically allocated. You don't know when it is allocated other than it's there before it can be used. Typically, it's just created when the program is loaded (i.e, before execution actually starts). Jul 22 '05 #5

 P: n/a Ron Natalie wrote: Steven T. Hatton wrote: I agree. At what point is the memory (typically) allocated? S::c is statically allocated. You don't know when it is allocated other than it's there before it can be used. Typically, it's just created when the program is loaded (i.e, before execution actually starts). I was speaking in terms used when discussing issues related to the use of data members verses pointers or references to data members. For example, if we have an indirect recursive structure such as: #include class B; class A{ B b; }; class B{ A a; }; It is commonly asserted that the above code will not compile because 'the compiler doesn't know how to allocate the memory for b'. I guess that means the compiler doesn't have sufficient information to determine the relative offset for the end of the storage location intended to hold the instance B A::b; So my question might be rephrased: when is the memory allocation determined for the static data member? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #6

 P: n/a Steven T. Hatton wrote: It is commonly asserted that the above code will not compile because 'the compiler doesn't know how to allocate the memory for b'. It knows how, it just doesn't know how much :-). Non-static members must be of complete types, 9.2/8. So my question might be rephrased: when is the memory allocation determined for the static data member? At the point of definition. It's declaration in the class is allowed to be an incomplete type. See 9.4.2/2. The definition (where you have const C S::c = C(42);) does require the complete type. Jul 22 '05 #7

 P: n/a Steven T. Hatton wrote: Ron Natalie wrote:Steven T. Hatton wrote:I agree. At what point is the memory (typically) allocated?S::c is statically allocated. You don't know when it is allocatedother than it's there before it can be used. Typically, it's justcreated when the program is loaded (i.e, before execution actuallystarts). I was speaking in terms used when discussing issues related to the use of data members verses pointers or references to data members. For example, if we have an indirect recursive structure such as: #include class B; class A{ B b; }; class B{ A a; }; It is commonly asserted that the above code will not compile because 'the compiler doesn't know how to allocate the memory for b'. I guess that means the compiler doesn't have sufficient information to determine the relative offset for the end of the storage location intended to hold the instance B A::b; Right. The _size_ of the object is the problem here. So my question might be rephrased: when is the memory allocation determined for the static data member? Memory allocation for any object is determined when the object has a complete type. V Jul 22 '05 #8

 P: n/a Victor Bazarov wrote: Steven T. Hatton wrote: > So my question might be rephrased: when is the memory allocation determined for the static data member? Memory allocation for any object is determined when the object has a complete type. So, in the example I posted, that would be when the member declaration S::C s is encountered in the struct definition. Here's just something to think about: #include using std::cout; using std::endl; using std::ostream; class C { int _v; public: C(const int& v = 0) :_v(v) {} ostream& print(ostream& out) const { return out << _c._v << " " << _v; } static const C _c; }; struct S { static const C c; }; const C S::c = C(42); ostream& operator<<(ostream& out, const S& s) { s.c.print(out); return out; } const C C::_c = C(1066); int main() { S s; cout << s << endl; return 0; } -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #9

 P: n/a Steven T. Hatton wrote: Victor Bazarov wrote:Steven T. Hatton wrote: > So my question might be rephrased: when is the memoryallocation determined for the static data member?Memory allocation for any object is determined when the object hasa complete type. So, in the example I posted, that would be when the member declaration S::C s is encountered in the struct definition. Here's just something to think about: So, have _you_ thought about it? #include using std::cout; using std::endl; using std::ostream; class C { int _v; public: C(const int& v = 0) :_v(v) {} ostream& print(ostream& out) const { return out << _c._v << " " << _v; } static const C _c; That's a declaration. }; struct S { static const C c; That's another declaration. }; const C S::c = C(42); That's a definition. No problem. 'C' is a complete type. ostream& operator<<(ostream& out, const S& s) { s.c.print(out); return out; } const C C::_c = C(1066); That's another definition. Again, no problem. int main() { S s; cout << s << endl; return 0; } So I've thought about it. Now what? V Jul 22 '05 #10

 P: n/a Victor Bazarov wrote: Steven T. Hatton wrote: Victor Bazarov wrote:Steven T. Hatton wrote: > So my question might be rephrased: when is the memoryallocation determined for the static data member?Memory allocation for any object is determined when the object hasa complete type. So, in the example I posted, that would be when the member declaration S::C s is encountered in the struct definition. Here's just something to think about: So, have _you_ thought about it? #include using std::cout; using std::endl; using std::ostream; class C { int _v; public: C(const int& v = 0) :_v(v) {} ostream& print(ostream& out) const { return out << _c._v << " " << _v; } static const C _c; That's a declaration. }; C is a complete type. So can we say C::_c is allocated at this point? -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #11

 P: n/a Steven T. Hatton wrote: Victor Bazarov wrote:Steven T. Hatton wrote:Victor Bazarov wrote: Steven T. Hatton wrote:> So my question might be rephrased: when is the memory>allocation determined for the static data member?Memory allocation for any object is determined when the object hasa complete type. So, in the example I posted, that would be when the member declarationS::C s is encountered in the struct definition.Here's just something to think about:So, have _you_ thought about it?#include using std::cout;using std::endl;using std::ostream;class C { int _v;public: C(const int& v = 0) :_v(v) {} ostream& print(ostream& out) const { return out << _c._v << " " << _v; } static const C _c;That's a declaration.}; C is a complete type. So can we say C::_c is allocated at this point? First of all, C is not a complete type until the closing curly brace is encountered. So, no, it's not a complete type. Second, no, C::_c is not allocated at that point. Any object is only allocated when it's _defined_ not when it's _declared_. V Jul 22 '05 #12

 P: n/a Victor Bazarov wrote: Steven T. Hatton wrote: Victor Bazarov wrote:Steven T. Hatton wrote:Victor Bazarov wrote: >Steven T. Hatton wrote:>>> So my question might be rephrased: when is the memory>>>allocation determined for the static data member?>>Memory allocation for any object is determined when the object has>a complete type. So, in the example I posted, that would be when the member declarationS::C s is encountered in the struct definition.Here's just something to think about:So, have _you_ thought about it? #include using std::cout;using std::endl;using std::ostream;class C { int _v;public: C(const int& v = 0) :_v(v) {} ostream& print(ostream& out) const { return out << _c._v << " " << _v; } static const C _c;That's a declaration. }; C is a complete type. So can we say C::_c is allocated at this point? First of all, C is not a complete type until the closing curly brace is encountered. My eyes must be playing tricks on me. Second, no, C::_c is not allocated at that point. Any object is only allocated when it's _defined_ not when it's _declared_. "Memory allocation for any object is determined when the object has a complete type." What about this? int foo(int i) { int x; return x * i; } -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #13

 P: n/a Steven T. Hatton wrote: C is a complete type. So can we say C::_c is allocated at this point? No, we say it is defined. Jul 22 '05 #14

 P: n/a Steven T. Hatton wrote: Victor Bazarov wrote:Steven T. Hatton wrote:Victor Bazarov wrote: Steven T. Hatton wrote: >Victor Bazarov wrote:>>>>>>Steven T. Hatton wrote:>>>>>>>So my question might be rephrased: when is the memory>>>>>allocation determined for the static data member?>>>>Memory allocation for any object is determined when the object has>>a complete type.>>>So, in the example I posted, that would be when the member declaration>S::C s is encountered in the struct definition.>>Here's just something to think about:So, have _you_ thought about it? >#include >>using std::cout;>using std::endl;>using std::ostream;>>class C {> int _v;>public:>> C(const int& v = 0)> :_v(v)> {}>> ostream& print(ostream& out) const> {> return out << _c._v << " " << _v;> }>> static const C _c;That's a declaration. >}; C is a complete type. So can we say C::_c is allocated at this point?First of all, C is not a complete type until the closing curly brace isencountered. My eyes must be playing tricks on me.Second, no, C::_c is notallocated at that point. Any object is only allocated when it's _defined_not when it's _declared_. "Memory allocation for any object is determined when the object has a complete type." Determination of memory allocation (the ability to allocate memory) and the actual _act_ of allocating memory are two different things. You need to be a bit clearer about what you ask. Memory is allocated when a static or automatic object is defined. For now we can probably leave dynamic objects alone. What about this? int foo(int i) { int x; return x * i; } What about it? As far as I can tell it produces undefined behaviour because 'x' has indeterminate value. V Jul 22 '05 #15

 P: n/a Ron Natalie wrote: Steven T. Hatton wrote: C is a complete type. So can we say C::_c is allocated at this point? No, we say it is defined. Weird. I say it is declared. V Jul 22 '05 #16

 P: n/a "Steven T. Hatton" wrote in news:6b********************@speakeasy.net: Victor Bazarov wrote: Steven T. Hatton wrote: Victor Bazarov wrote: Steven T. Hatton wrote:>Victor Bazarov wrote:>>>>>Steven T. Hatton wrote:>>>>> So my question might be rephrased: when is the memory>>>>>allocation determined for the static data member?>>>>Memory allocation for any object is determined when the object has>>a complete type.>>>So, in the example I posted, that would be when the member>declaration S::C s is encountered in the struct definition.>>Here's just something to think about:So, have _you_ thought about it? >#include >>using std::cout;>using std::endl;>using std::ostream;>>class C {> int _v;>public:>> C(const int& v = 0)> :_v(v)> {}>> ostream& print(ostream& out) const> {> return out << _c._v << " " << _v;> }>> static const C _c;That's a declaration. >}; C is a complete type. So can we say C::_c is allocated at this point? First of all, C is not a complete type until the closing curly brace is encountered. My eyes must be playing tricks on me. Care to elaborate? Second, no, C::_c is not allocated at that point. Any object is only allocated when it's _defined_ not when it's _declared_. "Memory allocation for any object is determined when the object has a complete type." What about this? int foo(int i) { int x; return x * i; } What about it? You need to be clearer about what exactly you're asking... when is the memory for x allocated, when is the memory for i allocated, when is the memory for the returned int allocated, when is the memory for the result of "x * i" allocated, how many lines does this function have? Jul 22 '05 #17

 P: n/a Steven T. Hatton wrote: [...] I really wasn't trying to play gotcha. I just found the example thought provoking. I really don't understand the subtelties of compiling and linking. I can (I believe) compile the class with the static member declared, but not compile the definition of the static member at the same time. I later link the two compiled object files to get a fully functional class with its static members. If I never use the static members, the code will (I believe) compile and link just fine. Compilation and linking of static members of non-local classes is very similar to that of any other global object, and, not surprisingly, any function. If you just declare a function void foo(); and never define it, it will compile and link fine as long as you don't try to use the function. I am not sure how this can be as daunting as you make us believe you see it. Victor Jul 22 '05 #19

 P: n/a Victor Bazarov wrote: Compilation and linking of static members of non-local classes is very similar to that of any other global object, and, not surprisingly, any function. If you just declare a function void foo(); and never define it, it will compile and link fine as long as you don't try to use the function. I am not sure how this can be as daunting as you make us believe you see it. Victor We aren't talking about a function. IIRC, a function in C++ is specifically _not_ an object in any sense of the word. I'm not really doubting that the memory is allocated when the definition is compiled. I'm just wondering how how the pieces are put together. In view of the fact that the point of definition of a static member object of class type is where a constructor will be invoked, it makes sense that it will be physically allocated when that definition's object code representation is loaded. After examining the object files emitted by the compiler for various builds, I can see that if the static member is not used, it is not even present in the object file containing the entry point. -- "If our hypothesis is about anything and not about some one or more particular things, then our deductions constitute mathematics. Thus mathematics may be defined as the subject in which we never know what we are talking about, nor whether what we are saying is true." - Bertrand Russell Jul 22 '05 #20

 P: n/a Steven T. Hatton wrote: Here's just something to think about: [...] Here is an interesting side effect: #include class C { int v; public: C(const int& v = 0) :v(v) {} static const C c; }; const C C::c = 1066; int main() { using std::cout; using std::endl; C obj; cout<<&obj.c<

 P: n/a Steven T. Hatton wrote: After examining the object files emitted by the compiler for various builds, I can see that if the static member is not used, it is not even present in the object file containing the entry point. Since I am not a language lawyer I am positive I will be corrected promptly. Since C++ implementations are allowed to defer the contructions of objects defined in a given translation unit until the first use of any object or function defined in the translation unit it would not suprise me at all if a compiler 'optimized' it away in this circumstance. I do not know the "legal" wording of it but I believe it is referred to as lazy evaluation and in spirit of the Golden Rule of C++ - you don't pay for something you don't use. That could be speed, size, etc. I do not know if this is technically correct as 'bible' though, just my simple understanding. -- Chris Johnson ~ ~ :wq Jul 22 '05 #22