8

Consider the sample program below:

#include <iostream>

using namespace std;

class test
{
   public:
      static const float data;
};

float const test::data = 10;   // Line1


int main()
{
   cout << test::data;
   cout << "\n";

   return 0;
}

Please note the comment Line1 in the sample code.

Questions:

  1. Is Line1 doing the initialization of the date member data?
  2. Is Line1 the only way to initialize a static const non-integral data member?

5 Answers 5

8

Is Line1 doing the initialization of the date member data?

It certainly is, as well as providing the definition of the object. Note that this can only be done in a single translation unit, so if the class definition is in a header file, then this should be in a source file.

Is Line1 the only way to initialize a static const non-integral data member?

In C++03 it was. In C++11, any static member of const literal type can have an initialiser in the class definition. You still need a definition of the member if it's "odr-used" (roughly speaking, if you do anything that needs its address, not just its value). In this case, the definition again needs to be in a single translation unit, and must not have an initialiser (since there's already one in the class definition).

3
  • Thanks. So if i do Line1 in header file or in multiple source files, then it would be an error due to multiple definition right? Commented Dec 13, 2011 at 14:31
  • 2
    @LinuxPenseur: Yes, that's correct. You'd be breaking the "One Definition Rule". Commented Dec 13, 2011 at 14:32
  • 2
    What was the rationale for C++03 treating integral types differently than non-integral types here? Anyone know? Commented Oct 18, 2012 at 20:38
5

In contemporary C++ you can initialize any constant expression inline. This requires a change of syntax:

class test
{
   public:
      static constexpr float data = 10.0f;
};

float constexpr test::data;
6
  • @jrok: there's no redeclaration there, just a definition of a previously declared object. Commented Dec 13, 2011 at 14:29
  • @jrok: Yes, you're right, that was just an oversight. Fixed! Note that you might not even need the definition at all.
    – Kerrek SB
    Commented Dec 13, 2011 at 14:37
  • Exactly, definition it's not needed.
    – jrok
    Commented Dec 13, 2011 at 14:39
  • 1
    @jrok: well, it's sometimes not needed. If you want to take the address, &test::data, you will need the definition. It depends on how you're using it, i.e. whether you want only the value or the actual object.
    – Kerrek SB
    Commented Dec 13, 2011 at 14:46
  • I think you could specify the version of the C++ in your example to improve it. I found "contemporary C++" misleading, imagine for people reading this thread in 4-5 years ;)
    – ForceMagic
    Commented Sep 22, 2012 at 3:32
4
  1. Line1 does definition of the static data member data, which includes setting its value.
  2. For static data members of non-integral types, member definition is indeed the only place to set a value. For integers, longs, enums, etc. you can put the value in with the declaration. You must still include a definition, but in that case you must not put in any value.

EDIT: As Mike Seymor pointed out, the #2 is out of date. According to the new C++11 standard, the alternative syntax that was reserved only for integral types by the 1998 and C++03 standards has been extended to all constants, regardless of their type.

3
  • 2
    Your second answer is out of date. In C++11, any static member of const literal type (not just integer types) can be initialised in the class definition. Commented Dec 13, 2011 at 14:26
  • 1
    @MikeSeymour Thanks for pointing this out! I have updated the answer. I haven't been coding in C++ much in the last ten years, so I missed this useful detail of the new standard. Thanks again for the correction! Commented Dec 13, 2011 at 14:34
  • @dasblinkenlight Can you provide links or sources that say C++98 allowed in-class-initializations for integral types in 1998 and also, the references for C++03 standards extending them to all constants. I see many tell them, but couldn't find any authentic reference. It will help me to present to my colleagues and tell them, be it any modern gcc compiler, we could skip the in-class-initialization for static const int. As they don't take up storage space.
    – smRaj
    Commented Sep 20, 2014 at 10:34
2
  1. Yes.

2.

In C++11, you can say

class test {
public:
    constexpr static float data = 10.0; // data is implicitly const
};

In C++03, it's Yes.

0

Is Line1 doing the initialization of the date member data?

Yes.

Is Line1 the only way to initialize a static const non-integral data member?

Yes.

Not the answer you're looking for? Browse other questions tagged or ask your own question.