const static member

Discussion in 'C++' started by Chameleon, Nov 3, 2008.

  1. Chameleon

    Chameleon Guest

    The following code produces strange errors in mingw.
    Is a C++ problem or compiler problem?
    ----------------------------
    #include <list>

    class A
    {
    static const int B = 0;
    std::list<int> lst;
    void calc();
    };


    void A::calc()
    {
    lst.push_back(B); // produces 'undefined reference to A::B'
    int a = B;
    lst.push_back(a); // its ...ok!
    }

    int main() { return 0; }
    ----------------------------
    Chameleon, Nov 3, 2008
    #1
    1. Advertising

  2. Chameleon

    Guest

    On Nov 3, 3:34 pm, Chameleon <> wrote:
    > The following code produces strange errors in mingw.
    > Is a C++ problem or compiler problem?
    > ----------------------------
    > #include <list>
    >
    > class A
    > {
    > static const int B = 0;


    Sadly, the above line does not define
    storage for B, but only declares it.

    You also need this defined somewhere:

    const int A::B;

    I believe it's just working for you in the
    second case because it's getting optimized
    away. Compiler bug, I guess.

    Sean
    , Nov 3, 2008
    #2
    1. Advertising

  3. Chameleon wrote:
    > The following code produces strange errors in mingw.
    > Is a C++ problem or compiler problem?


    It is a problem with your code. In the C++98 specification all static
    members of the class used in the program, have to be explicitly defined.
    You failed to define the member, which is why from C++98 point of view
    your code is ill-formed in _both_ contexts.

    The revised C++ standard is more elaborate in this respect. Your
    compiler's behavior is consistent with the revised specification.

    > ----------------------------
    > #include <list>
    >
    > class A
    > {
    > static const int B = 0;
    > std::list<int> lst;
    > void calc();
    > };
    >
    >
    > void A::calc()
    > {
    > lst.push_back(B); // produces 'undefined reference to A::B'


    'push_back' method accepts its parameters by constant reference and the
    parameter and argument type matches exactly in this case, which means
    that in the above context the reference is bound directly to the lvalue
    'A::B'. This requires a definition of 'A::B' object. You forgot to
    provide one. This is why you get an error.

    > int a = B;
    > lst.push_back(a); // its ...ok!
    > }


    In this context the value of 'B' can be used as an rvalue, an integral
    constant expression. There's no requirement to define 'A::B' for this
    particular context.

    --
    Best regards,
    Andrey Tarasevich
    Andrey Tarasevich, Nov 3, 2008
    #3
  4. Chameleon

    James Kanze Guest

    On Nov 3, 10:15 pm, wrote:
    > On Nov 3, 3:34 pm, Chameleon <> wrote:


    > > The following code produces strange errors in mingw. Is a
    > > C++ problem or compiler problem?


    Your problem. The code is not legal C++.

    > > ----------------------------
    > > #include <list>


    > > class A
    > > {
    > >     static const int B = 0;


    > Sadly, the above line does not define storage for B, but only
    > declares it.


    > You also need this defined somewhere:


    >   const int A::B;


    > I believe it's just working for you in the second case because
    > it's getting optimized away.  Compiler bug, I guess.


    No compiler bug. Not defining a variable which has been used is
    undefined behavior, so anything the compiler does with it is
    fine. In practice, given a declaration which can be used as an
    integral constant expression, most compilers will only require
    the definition if it is used in a context where there was not an
    immediate lvalue to rvalue conversion. When you use it to
    initialize another int, there is an immediate lvalue to rvalue
    conversion; list<int>::push_back, on the other hand, takes a
    reference, so there is no lvalue to rvalue conversion.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Nov 3, 2008
    #4
    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,849
    Rakesh Sinha
    Jan 13, 2005
  2. Dave
    Replies:
    10
    Views:
    35,285
    Ron Natalie
    May 22, 2005
  3. Javier
    Replies:
    2
    Views:
    561
    James Kanze
    Sep 4, 2007
  4. er
    Replies:
    3
    Views:
    382
  5. fungus
    Replies:
    13
    Views:
    887
    fungus
    Oct 31, 2008
Loading...

Share This Page