linking error for static member variables

Discussion in 'C++' started by aaragon, Oct 20, 2008.

  1. aaragon

    aaragon Guest

    Hi everyone,

    I have a linking error when using gcc4.2 and static member variables.
    The class template definition is something around the following:

    template<>
    class Element<L2_t> : public Element_common<L2, Side<2,2> > {

    public:

    static const ubyte_t dim_ = 2;
    static const ubyte_t num_nodes_ = 2;
    static const ubyte_t gauss_pts_= 3;

    // member functions
    };

    Undefined symbols:
    "fea::Element<(fea::Element_type)1>::gauss_pts_", referenced from:
    __ZN3fea7ElementILNS_12Element_typeE1EE10gauss_pts_E
    $non_lazy_ptr in element.o
    "fea::Element<(fea::Element_type)2>::gauss_pts_", referenced from:
    __ZN3fea7ElementILNS_12Element_typeE2EE10gauss_pts_E
    $non_lazy_ptr in element.o
    "fea::Element<(fea::Element_type)3>::gauss_pts_", referenced from:
    __ZN3fea7ElementILNS_12Element_typeE3EE10gauss_pts_E
    $non_lazy_ptr in element.o
    ld: symbol(s) not found

    The strange thing is that I have many other static variables with the
    same kind of definition (same type and const as you can see) but it
    only complaints about the gauss_pts_ member variable. I solved the
    problem by moving the definition to the cpp file as follows:

    // in cpp file
    const ubyte_t Element<L2_t>::gauss_pts_ = 3;

    But I want to understand really what is happening here. When I compile
    the code with gcc4.3, the problem disappears. So, is this a bug in the
    compiler?

    Thanks for the help,

    aa
    aaragon, Oct 20, 2008
    #1
    1. Advertising

  2. aaragon

    aaragon Guest

    On Oct 20, 7:45 am, Victor Bazarov <> wrote:
    > aaragon wrote:
    > > I have a linking error when using gcc4.2 and static member variables.
    > > The class template definition is something around the following:

    >
    > >    template<>
    > >    class Element<L2_t> : public Element_common<L2, Side<2,2> > {

    >
    > >    public:

    >
    > >            static const ubyte_t dim_ = 2;
    > >            static const ubyte_t num_nodes_ = 2;
    > >            static const ubyte_t gauss_pts_= 3;

    >
    > WTH is 'ubyte_t'?
    >
    >
    >


    just a type definition to cope with the way I name things.

    >
    >
    > >         // member functions
    > >         };

    >
    > > Undefined symbols:
    > >   "fea::Element<(fea::Element_type)1>::gauss_pts_", referenced from:
    > >       __ZN3fea7ElementILNS_12Element_typeE1EE10gauss_pts_E
    > > $non_lazy_ptr in element.o
    > >   "fea::Element<(fea::Element_type)2>::gauss_pts_", referenced from:
    > >       __ZN3fea7ElementILNS_12Element_typeE2EE10gauss_pts_E
    > > $non_lazy_ptr in element.o
    > >   "fea::Element<(fea::Element_type)3>::gauss_pts_", referenced from:
    > >       __ZN3fea7ElementILNS_12Element_typeE3EE10gauss_pts_E
    > > $non_lazy_ptr in element.o
    > > ld: symbol(s) not found

    >
    > > The strange thing is that I have many other static variables with the
    > > same kind of definition (same type and const as you can see) but it
    > > only complaints about the gauss_pts_ member variable. I solved the
    > > problem by moving the definition to the cpp file as follows:

    >
    > >         // in cpp file
    > >    const ubyte_t Element<L2_t>::gauss_pts_ = 3;

    >
    > > But I want to understand really what is happening here.

    >
    > Not much.  Any static member variable/constant has to be defined if used
    > outside of the class.  Since you didn't show us how those constants are
    > used, the assumption is that they *are* used outside and *must* be
    > defined or you're in violation of the ODR.
    >



    It is defined, when inside a class you do something like

    static const int test = 2;

    you're defining inline the value of the constant. That is exacly what
    I was doing before, but the linker couldn't find it. Weird thing is
    that only happened with one varible, the other static constants were
    defined in the same way, but they didn't give me problems. So there
    must be a problem with the copmiler.


    >  > When I compile
    >
    > > the code with gcc4.3, the problem disappears. So, is this a bug in the
    > > compiler?

    >
    > Not from where I sit.
    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask
    aaragon, Oct 20, 2008
    #2
    1. Advertising

  3. aaragon

    aaragon Guest

    On Oct 20, 2:38 pm, Victor Bazarov <> wrote:
    > aaragon wrote:
    > > On Oct 20, 7:45 am, Victor Bazarov <> wrote:
    > >> aaragon wrote:
    > >>> I have a linking error when using gcc4.2 and static member variables.
    > >>> The class template definition is something around the following:
    > >>>    template<>
    > >>>    class Element<L2_t> : public Element_common<L2, Side<2,2> > {
    > >>>    public:
    > >>>            static const ubyte_t dim_ = 2;
    > >>>            static const ubyte_t num_nodes_ = 2;
    > >>>            static const ubyte_t gauss_pts_= 3;
    > >> WTH is 'ubyte_t'?

    >
    > > just a type definition to cope with the way I name things.

    >
    > Well, the language prohibits initialisations of static const data
    > members *unless* they are of an *integral type*.  If your 'ubyte_t' is
    > not integral, your code is ill-formed.
    >


    u_byte is just a type definition for an unsigned short, which is of an
    integral type. The rest of the static constant member variables were
    also of the same type but only this one game the problem. Weird.

    >
    >
    > >>>         // member functions
    > >>>         };
    > >>> Undefined symbols:
    > >>>   "fea::Element<(fea::Element_type)1>::gauss_pts_", referenced from:
    > >>>       __ZN3fea7ElementILNS_12Element_typeE1EE10gauss_pts_E
    > >>> $non_lazy_ptr in element.o
    > >>>   "fea::Element<(fea::Element_type)2>::gauss_pts_", referenced from:
    > >>>       __ZN3fea7ElementILNS_12Element_typeE2EE10gauss_pts_E
    > >>> $non_lazy_ptr in element.o
    > >>>   "fea::Element<(fea::Element_type)3>::gauss_pts_", referenced from:
    > >>>       __ZN3fea7ElementILNS_12Element_typeE3EE10gauss_pts_E
    > >>> $non_lazy_ptr in element.o
    > >>> ld: symbol(s) not found
    > >>> The strange thing is that I have many other static variables with the
    > >>> same kind of definition (same type and const as you can see) but it
    > >>> only complaints about the gauss_pts_ member variable. I solved the
    > >>> problem by moving the definition to the cpp file as follows:
    > >>>         // in cpp file
    > >>>    const ubyte_t Element<L2_t>::gauss_pts_ = 3;
    > >>> But I want to understand really what is happening here.
    > >> Not much.  Any static member variable/constant has to be defined if used
    > >> outside of the class.  Since you didn't show us how those constants are
    > >> used, the assumption is that they *are* used outside and *must* be
    > >> defined or you're in violation of the ODR.

    >
    > > It is defined, when inside a class you do something like

    >
    > >    static const int test = 2;

    >
    > > you're defining inline the value of the constant.

    >
    > Nope.  It's declared and initialised.  It's not defined.  It's only
    > defined when you can say that the memory for it is allocated and *where*
    > it is allocated.  Unless you do
    >
    >    const int <classname>::test;
    >
    > in the *namespace* scope somewhere in a translation unit, the data
    > member is *undefined*.
    >
    >  > That is exacly what
    >
    > > I was doing before, but the linker couldn't find it. Weird thing is
    > > that only happened with one varible, the other static constants were
    > > defined in the same way, but they didn't give me problems. So there
    > > must be a problem with the copmiler.

    >
    > Sure.  What else could it be?..  Stupid compilers!


    Indeed, stupid compilers!

    >
    > V
    > --
    > Please remove capital 'A's when replying by e-mail
    > I do not respond to top-posted replies, please don't ask


    Thanks for answering my post.

    aa
    aaragon, Oct 20, 2008
    #3
    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. 0to60
    Replies:
    4
    Views:
    515
    jeffc
    Nov 21, 2003
  2. Siemel Naran
    Replies:
    4
    Views:
    805
    Micah Cowan
    Jan 12, 2005
  3. iwl
    Replies:
    3
    Views:
    657
  4. dolphin
    Replies:
    3
    Views:
    1,342
    Pete Becker
    Dec 5, 2007
  5. Replies:
    9
    Views:
    941
Loading...

Share This Page