error: invalid use of nonstatic data member

Discussion in 'C++' started by The|Godfather, Oct 23, 2006.

  1. Hi everybody,

    I read Scotte Meyer's "Effective C++" book twice and I know that
    he mentioned something specific about constructors and destructors that
    was related to the
    following error/warning: "error: invalid use of nonstatic data member "

    However, he did NOT mention this error in the book explicitly.It
    happens always in the constructor when you try to initialize some data
    members in the constructor and try to accsess other data members. Of
    course,one can always move the initialization away from the
    constructor , but that is not the goal:

    UP_SQLPrepQuery::StatementInternals::StatementInternals(bool & status)
    : nParams(0),
    capacity(0),
    tuple_num(0),
    alter_session_statement(false),
    select_statement(false)
    {sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    __FILE__)->prep_cnt++);
    }

    The error is in the line:

    sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    __FILE__)->prep_cnt++);
    }

    Here , I try to get some value through a function. Scott said something
    about NOT doing that in constructors, but I am not sure and I could
    NOT find anything. The problem is with the Function
    embeddedConnection.GetConnectionInternals(), which should return a
    pointer to an object.

    I am using gcc (GCC) 3.4.2 under: x86_64 GNU/Linux
    Please, advise.

    Cheers,
    Dragomir Stanchev
     
    The|Godfather, Oct 23, 2006
    #1
    1. Advertising

  2. The|Godfather

    Miles Bader Guest

    It would help if you would actually give the related declarations...

    -miles

    --
    Is it true that nothing can be known? If so how do we know this? -Woody Allen
     
    Miles Bader, Oct 23, 2006
    #2
    1. Advertising

  3. Disclaimer: I don't read 'gnu.gcc.help' newsgroup, so I removed it
    from my reply. BTW, did you know there is 'gnu.g++.help'?

    The|Godfather wrote:
    > I read Scotte Meyer's "Effective C++" book twice and I know that
    > he mentioned something specific about constructors and destructors
    > that was related to the
    > following error/warning: "error: invalid use of nonstatic data member
    > "
    >
    > However, he did NOT mention this error in the book explicitly.It
    > happens always in the constructor when you try to initialize some data
    > members in the constructor and try to accsess other data members. Of
    > course,one can always move the initialization away from the
    > constructor , but that is not the goal:
    >
    > UP_SQLPrepQuery::StatementInternals::StatementInternals(bool & status)
    >> nParams(0),

    > capacity(0),
    > tuple_num(0),
    > alter_session_statement(false),
    > select_statement(false)
    > {sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > __FILE__)->prep_cnt++);
    > }


    So, _assuming_ it's written correctly, I can divine that 'nParams',
    'capacity', 'tuple_num', 'alter_session_statement', 'select_statement',
    are all non-static members of 'StatementInternals' class, which resides
    in 'UP_SQLPrepQuery' namespace.

    Nothing else can be said about the class or the body of the c-tor.

    >
    > The error is in the line:
    >
    > sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > __FILE__)->prep_cnt++);
    > }


    So? What's "stmt_internals"? What's "embeddedConnection"?

    > Here , I try to get some value through a function. Scott said
    > something about NOT doing that in constructors, but I am not sure and
    > I could NOT find anything. The problem is with the Function
    > embeddedConnection.GetConnectionInternals(), which should return a
    > pointer to an object.


    There is no function 'embeddedConnection.GetConnectionInternals()'.
    The syntax suggests that 'GetConnectionInternals' is a _member_ of
    the class, of which 'embeddedConnection' _object_ is an instance.
    If 'embeddedConnection' *is* a type, you need '::' instead of '.'
    here:

    ... embeddedConnection::GetConnectionInternals() ...

    but it's just a guess, given absence of any information about it.

    > I am using gcc (GCC) 3.4.2 under: x86_64 GNU/Linux
    > Please, advise.


    You should probably use G++...

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 23, 2006
    #3
  4. The|Godfather

    mlimber Guest

    The|Godfather wrote:
    > I read Scotte Meyer's "Effective C++" book twice and I know that
    > he mentioned something specific about constructors and destructors that
    > was related to the
    > following error/warning: "error: invalid use of nonstatic data member "
    >
    > However, he did NOT mention this error in the book explicitly.


    Huh? Scotte (or Scott, as most people call him) mentioned something
    specific related to that error but he did not mention that error
    explicitly, so how do you know he was referring to that error
    specifically?

    > It
    > happens always in the constructor when you try to initialize some data
    > members in the constructor and try to accsess other data members.


    You can't *initialize* static data members in the ctor
    (http://www.parashift.com/c -faq-lite/ctors.html#faq-10.10), but you
    can *use* them there. Regarding the "other data members," see this FAQ:

    http://www.parashift.com/c -faq-lite/ctors.html#faq-10.7

    > Of
    > course,one can always move the initialization away from the
    > constructor ,


    Right, to enforce proper initialization, especially in the case that
    the constructor needs to call a virtual function. This is generally
    superior to forcing the user to call an Init() function, which can
    easily be forgotten, leaving the object uninitialized. This example is
    drawn from Sutter and Alexandrescu's _C++ Coding Standards_ (Item 49):

    class B // Hierarchy root
    {
    protected:
    B() { /*...*/ }

    // Called right after construction
    virtual void PostInitialize() { /*...*/ }

    public:

    // Interface for creating objects
    template<class T>
    static std::auto_ptr<T> Create()
    {
    std::auto_ptr<T> p( new T );
    p->PostInitialize();
    return p;
    }
    };

    // A derived class
    class D : public B { /*...*/ };

    // Creating an initialized D object
    std::auto_ptr<D> p = D::Create<D>();

    > but that is not the goal:
    >
    > UP_SQLPrepQuery::StatementInternals::StatementInternals(bool & status)
    > : nParams(0),
    > capacity(0),
    > tuple_num(0),
    > alter_session_statement(false),
    > select_statement(false)
    > {sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > __FILE__)->prep_cnt++);
    > }
    >
    > The error is in the line:
    >
    > sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > __FILE__)->prep_cnt++);
    > }
    >
    > Here , I try to get some value through a function.


    You have not followed the FAQ on how to post code that doesn't work
    (http://www.parashift.com/c -faq-lite/how-to-post.html#faq-5.8). Not
    only is it helpful, in this case it is necessary because you don't
    provide enough information to divine what you are trying to do. Please
    post a *minimal* but *complete* program (i.e., one that we can cut and
    paste directly to our editors unchanged) that demonstrates your
    problem.

    Cheers! --M
     
    mlimber, Oct 23, 2006
    #4
  5. Ok,
    I apologize for not posting working code , just did NOT have any time
    yesterday.
    Here is full report now:

    gcc --version: gcc (GCC) 3.4.2
    uname -rmo: 2.6.5-7.201-smp x86_64 GNU/Linux
    compile command:
    gcc -c -I/users/dstanche/problem test1.cpp
    Error Message:
    "test1.cpp: In constructor
    `test1::StatementInternals::StatementInternals()':
    test1.cpp:8: error: invalid use of nonstatic data member
    'test1::stmt_internals' "

    CODE :

    example.h:
    ------------
    class example {

    public:
    example() {;}
    inline int giveIt(){return 2;}
    };

    --------
    test1.h
    -------
    #include <example.h>

    class test1 :example{
    class StatementInternals;
    public:

    test1();
    private:
    StatementInternals * stmt_internals;


    };

    ---------
    test1I.h
    ---------
    class test1::StatementInternals
    {
    public:
    StatementInternals();
    unsigned long *length;
    bool select_statement;
    int stmt_counter;

    };
    --------
    test1.cpp
    -------
    #include <test1.h>
    #include <test1I.h>

    test1::StatementInternals::StatementInternals()
    : length(0), select_statement(0)

    {
    stmt_counter=stmt_internals->giveIt(); // THE PROBLEM LINE IS THIS
    ONE
    }

    test1::test1():stmt_internals(new StatementInternals){}


    int main() {

    return 0;
    }
    -------

    As you can see the code does not do anything special. I have NO idea
    why the problem occurs. Please advice.

    Dragomir Stanchev

    mlimber wrote:
    > The|Godfather wrote:
    > > I read Scotte Meyer's "Effective C++" book twice and I know that
    > > he mentioned something specific about constructors and destructors that
    > > was related to the
    > > following error/warning: "error: invalid use of nonstatic data member "
    > >
    > > However, he did NOT mention this error in the book explicitly.

    >
    > Huh? Scotte (or Scott, as most people call him) mentioned something
    > specific related to that error but he did not mention that error
    > explicitly, so how do you know he was referring to that error
    > specifically?
    >
    > > It
    > > happens always in the constructor when you try to initialize some data
    > > members in the constructor and try to accsess other data members.

    >
    > You can't *initialize* static data members in the ctor
    > (http://www.parashift.com/c -faq-lite/ctors.html#faq-10.10), but you
    > can *use* them there. Regarding the "other data members," see this FAQ:
    >
    > http://www.parashift.com/c -faq-lite/ctors.html#faq-10.7
    >
    > > Of
    > > course,one can always move the initialization away from the
    > > constructor ,

    >
    > Right, to enforce proper initialization, especially in the case that
    > the constructor needs to call a virtual function. This is generally
    > superior to forcing the user to call an Init() function, which can
    > easily be forgotten, leaving the object uninitialized. This example is
    > drawn from Sutter and Alexandrescu's _C++ Coding Standards_ (Item 49):
    >
    > class B // Hierarchy root
    > {
    > protected:
    > B() { /*...*/ }
    >
    > // Called right after construction
    > virtual void PostInitialize() { /*...*/ }
    >
    > public:
    >
    > // Interface for creating objects
    > template<class T>
    > static std::auto_ptr<T> Create()
    > {
    > std::auto_ptr<T> p( new T );
    > p->PostInitialize();
    > return p;
    > }
    > };
    >
    > // A derived class
    > class D : public B { /*...*/ };
    >
    > // Creating an initialized D object
    > std::auto_ptr<D> p = D::Create<D>();
    >
    > > but that is not the goal:
    > >
    > > UP_SQLPrepQuery::StatementInternals::StatementInternals(bool & status)
    > > : nParams(0),
    > > capacity(0),
    > > tuple_num(0),
    > > alter_session_statement(false),
    > > select_statement(false)
    > > {sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > > __FILE__)->prep_cnt++);
    > > }
    > >
    > > The error is in the line:
    > >
    > > sprintf(stmt_internals->stmt_name,"%llx",embeddedConnection.GetConnectionInternals(__LINE__,
    > > __FILE__)->prep_cnt++);
    > > }
    > >
    > > Here , I try to get some value through a function.

    >
    > You have not followed the FAQ on how to post code that doesn't work
    > (http://www.parashift.com/c -faq-lite/how-to-post.html#faq-5.8). Not
    > only is it helpful, in this case it is necessary because you don't
    > provide enough information to divine what you are trying to do. Please
    > post a *minimal* but *complete* program (i.e., one that we can cut and
    > paste directly to our editors unchanged) that demonstrates your
    > problem.
    >
    > Cheers! --M
     
    The|Godfather, Oct 24, 2006
    #5
  6. The|Godfather wrote:
    > Ok,
    > I apologize for not posting working code , just did NOT have any time
    > yesterday.
    > Here is full report now:
    >
    > gcc --version: gcc (GCC) 3.4.2
    > uname -rmo: 2.6.5-7.201-smp x86_64 GNU/Linux
    > compile command:
    > gcc -c -I/users/dstanche/problem test1.cpp
    > Error Message:
    > "test1.cpp: In constructor
    > `test1::StatementInternals::StatementInternals()':
    > test1.cpp:8: error: invalid use of nonstatic data member
    > 'test1::stmt_internals' "
    > [...]

    If I compile this sample in MS-VC++ 8 the error message is simply that
    stmt_internals is an undeclared identifier, which makes a bit more sense
    to me than g++'s message. The 'forward' declaration in the definition of
    test1 merely *declares* StatementInternals, it does not define it and so
    it is not a nested class in the classical sense.

    class test1 : example {
    class StatementInternals; // declares class name
    public:
    test1();
    private:
    StatementInternals * stmt_internals; // defines pointer
    };

    The definition of StatementInternals is at the same lexical level as
    test1 and at that point the private attribute of test1 is unknown.
    Besides, C and C++ do not really support access to implicitly referenced
    outer variables from lexically nested functions. The question is not
    just whether to allow it (using public/private modifiers) but how to
    implement it when you do. A more complicated stack layout is needed to
    get at the proper variable instance. This is a feature that you will
    find in Algol-60, Pascal and the like but not C(++). Nobody seems to
    care enough to request it, though. I don't.

    Regards, Jan
     
    Jan van Mastbergen, Oct 24, 2006
    #6
  7. Jan van Mastbergen wrote:
    > The|Godfather wrote:
    >> Ok,
    >> I apologize for not posting working code , just did NOT have any time
    >> yesterday.
    >> Here is full report now:
    >>
    >> gcc --version: gcc (GCC) 3.4.2
    >> uname -rmo: 2.6.5-7.201-smp x86_64 GNU/Linux
    >> compile command:
    >> gcc -c -I/users/dstanche/problem test1.cpp
    >> Error Message:
    >> "test1.cpp: In constructor
    >> `test1::StatementInternals::StatementInternals()':
    >> test1.cpp:8: error: invalid use of nonstatic data member
    >> 'test1::stmt_internals' "
    >> [...]

    > If I compile this sample in MS-VC++ 8 the error message is simply that
    > stmt_internals is an undeclared identifier, which makes a bit more
    > sense to me than g++'s message. The 'forward' declaration in the
    > definition of test1 merely *declares* StatementInternals, it does not
    > define it and so it is not a nested class in the classical sense.
    >
    > class test1 : example {
    > class StatementInternals; // declares class name
    > public:
    > test1();
    > private:
    > StatementInternals * stmt_internals; // defines pointer
    > };


    I think it's all much simpler. You cannot use 'stmt_internals' data
    member in the constructor of StatementInternals [nested] class simply
    because 'stmt_internals' is not a member of 'StatementInternals' and
    needs an instance of 'test1' to be used.

    The confusion is common among Java programmers switching to C++. In
    Java an instance of an outer class _automatically_ contains an instance
    of a nested class. In C++ it does not.

    struct Outer {
    int data;
    struct Inner { // type defined inside another type
    Inner() { // c-tor
    int i = data; // what's "data"?
    }
    };
    };

    'Inner' does not have a member named "data". 'Outer' does. 'Outer'
    does not have a data member of type 'Inner'. Constructing an 'Outer'
    object does not automatically construct an 'Inner' object, nor does
    any instance of 'Inner' have any pre-defined "path" to 'data'.

    > [..]


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Oct 24, 2006
    #7
  8. The|Godfather

    Miles Bader Guest

    "The|Godfather" <> writes:
    > class test1::StatementInternals
    > {
    > public:
    > StatementInternals();
    > unsigned long *length;
    > bool select_statement;
    > int stmt_counter;
    > };

    ....
    > test1::StatementInternals::StatementInternals()
    > : length(0), select_statement(0)
    > {
    > stmt_counter=stmt_internals->giveIt(); // THE PROBLEM LINE IS THIS
    > ONE

    ....
    > As you can see the code does not do anything special. I have NO idea
    > why the problem occurs. Please advice.


    Because the StatementInternals class has no data member called
    "stmt_internals", so there's no way the StatementInternals constructor
    can use such a member.

    StatementInternals has exactly the data members you declared above, no
    others.

    -Miles

    --
    Occam's razor split hairs so well, I bought the whole argument!
     
    Miles Bader, Oct 24, 2006
    #8
    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. Jinesh

    Static/NONstatic error!!

    Jinesh, Jan 5, 2004, in forum: C++
    Replies:
    8
    Views:
    11,896
    Heinz Ozwirk
    Jan 6, 2004
  2. Replies:
    3
    Views:
    547
  3. fl
    Replies:
    12
    Views:
    846
    Salt_Peter
    Dec 31, 2007
  4. Jeffrey
    Replies:
    7
    Views:
    440
    James Kanze
    Sep 30, 2008
  5. Computerjunkie
    Replies:
    0
    Views:
    1,024
    Computerjunkie
    Apr 6, 2012
Loading...

Share This Page