Iniitializing static const data?

Discussion in 'C++' started by Minti, Jul 2, 2004.

  1. Minti

    Minti Guest

    How do we initialize static const data in C++, I tried


    class Foo
    {
    static const std::string name = "MyName";
    };


    I don't see any reason as to why this must not work.

    Probably it is because that we are in a sense calling a non static
    function[ The constructor of std::string]. But any other soluction(?)
    to me would sound inelegant.

    But I see no rationale for not allowing

    class Foo
    {
    static const float bar = 23;
    };

    Can anybody put any _common_sense in this non-sense.


    --
    Imanpreet Singh Arora
    isingh AT acm DOT org
     
    Minti, Jul 2, 2004
    #1
    1. Advertising

  2. Minti wrote:
    >
    > How do we initialize static const data in C++, I tried
    >
    > class Foo
    > {
    > static const std::string name = "MyName";
    > };
    >
    > I don't see any reason as to why this must not work.
    >
    > Probably it is because that we are in a sense calling a non static
    > function[ The constructor of std::string]. But any other soluction(?)
    > to me would sound inelegant.
    >
    > But I see no rationale for not allowing
    >
    > class Foo
    > {
    > static const float bar = 23;
    > };
    >
    > Can anybody put any _common_sense in this non-sense.


    What you are missing is that the above is a declaration, not a definition.
    That is:
    if you put a static member in a class, you only have declared it!
    You still need a definition of that member somewhere and of course,
    like anywhere else, you put the initialization to the definition.

    Declaration: telling the compiler that somewhere, in a code snippet far far
    away, something exists and what it looks like
    Definition: reserves the actual memory for that something

    So back to your example:

    class Foo
    {
    static const std::string name; // Declaration
    };

    const std::string Foo::name = "MyName"; // Definition


    Remember
    There is the famous One-Definition-Rule. Which means:
    you can have as many declarations in a program as you want (as long
    as all of them coincide). But you can have only 1 defintion. Thus
    typically the following is done. The declaration (enclosed in the class
    declaration) goes into the header file, while the defintion (with the
    initialization) goes into the source code file, which implements the
    class functionality.

    --
    Karl Heinz Buchegger
     
    Karl Heinz Buchegger, Jul 2, 2004
    #2
    1. Advertising

  3. Minti wrote:
    > How do we initialize static const data in C++, I tried
    >
    >
    > class Foo
    > {
    > static const std::string name = "MyName";
    > };


    Initialisation of static constants is allowed in the class definition
    _only_ for integral types. Members of any other types (and arrays,
    pointers, references) has to be defined/initialised at the namespace
    level.

    >
    >
    > I don't see any reason as to why this must not work.


    The only reason relevant in comp.lang.c++ is that the Standard does
    not allow that.

    > Probably it is because that we are in a sense calling a non static
    > function[ The constructor of std::string]. But any other soluction(?)
    > to me would sound inelegant.


    I am not sure I understand the last sentence here.

    >
    > But I see no rationale for not allowing
    >
    > class Foo
    > {
    > static const float bar = 23;
    > };
    >
    > Can anybody put any _common_sense in this non-sense.


    Yes. Somebody definitely can, but you have to ask in comp.std.c++.
    The questions about _why_ things are in C++ the way they are belong
    there, not here. Here we can tell you _how_ to do things, but not
    usually _why_ (unless it's explicitly explained in the C++ language
    specification). Language lawyers and Standard Committee members are
    often found in comp.std.c++ where all "why" questions are discussed.

    Victor
     
    Victor Bazarov, Jul 2, 2004
    #3
  4. Minti

    JKop Guest

    Minti posted:

    > class Foo
    > {
    > static const std::string name = "MyName";
    > };



    Consider you have a project like so:

    monkey.cpp
    ape.cpp
    cow.cpp
    tiger.cpp
    fonte.cpp

    fonte.hpp


    Here's fonte.hpp:

    #ifndef INCLUDE_FONTE_HPP
    #define INCLUDE_FONTE_HPP

    class Foo
    {
    static const std::string name;
    };

    #endif

    Now consider that this header file is included into all of the above CPP
    files. If you actually define the variable "name" in the header file, then
    each translation unit would have it's own separate variable. You don't want
    this, you just want the one variable. How you do this is make "fonte.cpp"
    and put the following in it:

    #include "fonte.hpp"

    const std::string Foo::name = "BlahBlah";

    See what happens now: the actual variable is declared in a .CPP file, that's
    where the defintions go. If another CPP file, another translation unit,
    wants to access this variable, all it does is include "fonte.hpp"


    -JKop
     
    JKop, Jul 2, 2004
    #4
  5. Minti

    Minti Guest

    JKop <> wrote in message news:<gvgFc.3712$>...
    > Minti posted:
    >
    > > class Foo
    > > {
    > > static const std::string name = "MyName";
    > > };

    >
    >
    > Consider you have a project like so:
    >
    > monkey.cpp
    > ape.cpp
    > cow.cpp
    > tiger.cpp
    > fonte.cpp
    >
    > fonte.hpp
    >
    >
    > Here's fonte.hpp:
    >
    > #ifndef INCLUDE_FONTE_HPP
    > #define INCLUDE_FONTE_HPP
    >
    > class Foo
    > {
    > static const std::string name;
    > };
    >
    > #endif
    >
    > Now consider that this header file is included into all of the above CPP
    > files. If you actually define the variable "name" in the header file, then
    > each translation unit would have it's own separate variable. You don't want
    > this, you just want the one variable. How you do this is make "fonte.cpp"
    > and put the following in it:
    >
    > #include "fonte.hpp"
    >
    > const std::string Foo::name = "BlahBlah";
    >
    > See what happens now: the actual variable is declared in a .CPP file, that's
    > where the defintions go. If another CPP file, another translation unit,
    > wants to access this variable, all it does is include "fonte.hpp"



    Hmm... Thanks for the answer but if we look at this whole thing with
    an explanation that variables can only be declared in class
    definitions then indeed we have a contradiction

    class Foo
    {
    static const int foo = 23;
    };

    is allowed, the reason I believe is that it makes it easy to specify
    the size of the arrays.

    But this aan not be an explanation for making something incosistent.


    --
    Imanpreet Singh Arora "In order to paint 6 things are required:
    i"kaur" #AT# acm #DOT# org spirit, rhythm, thought, scenery, pen
    and ink"
    mv kaur singh
     
    Minti, Jul 3, 2004
    #5
  6. Minti

    JKop Guest

    Minti posted:


    > Hmm... Thanks for the answer but if we look at this whole thing with
    > an explanation that variables can only be declared in class
    > definitions then indeed we have a contradiction
    >
    > class Foo
    > {
    > static const int foo = 23;
    > };
    >
    > is allowed, the reason I believe is that it makes it easy to specify
    > the size of the arrays.
    >
    > But this aan not be an explanation for making something incosistent.



    My point is that no variable is created in your above code. Think of it as
    an "extern" statement. It's just telling the compiler that such and object
    exists, it's not saying that the variable is defined right here in this
    translation unit!

    The problem with your original code is that you were telling the compiler
    that this object exists, but the when it came to the linker, the linker
    couldn't find where the bloody thing was actually defined! That's why you
    put:

    const int Foo::foo = 23;

    not 50 times, not 12 times, not twice, but once in one sole translation
    unit. That way, when the linker sees loads of translation units saying that
    this certain variable exists, it just goes through all of the translation
    units looking for an actual definition, ie.:

    const int Foo:foo = 23;

    If it finds that more than once, then it's exactly the same as saying:


    int main()
    {
    int a;

    float a;

    a = 23;
    }


    -JKop
     
    JKop, Jul 3, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Rakesh Sinha
    Replies:
    4
    Views:
    1,880
    Rakesh Sinha
    Jan 13, 2005
  2. Dave
    Replies:
    10
    Views:
    35,400
    Ron Natalie
    May 22, 2005
  3. Replies:
    11
    Views:
    1,151
  4. Javier
    Replies:
    2
    Views:
    623
    James Kanze
    Sep 4, 2007
  5. er
    Replies:
    3
    Views:
    402
Loading...

Share This Page