error: invalid use of nonstatic data member

T

The|Godfather

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
 
V

Victor Bazarov

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 said:
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)
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
 
M

mlimber

The|Godfather said:
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 said:
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
 
T

The|Godfather

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
 
J

Jan van Mastbergen

The|Godfather said:
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
 
V

Victor Bazarov

Jan said:
The|Godfather said:
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
 
M

Miles Bader

The|Godfather said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top