C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Implementing static methods inside the class declaration.

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Isaac Rodriguez
Guest





PostPosted: Fri Dec 17, 2004 5:34 pm    Post subject: Implementing static methods inside the class declaration. Reply with quote



Hi,

Is this a bug in VC7.0, a bad programming practice, or both? I have a
singleton
class that is defined something like this:

class DatabaseMgr
{
public:

static DatabaseMgr& instance () {

static DatabaseMgr inst;
return inst;
}

void initialize (const String& filename) {

pDb_ = new Database(filename);
// and some other stuff.
inited = true;
}

Database* db () {

if( !inited_ ) {

throw MyException; // Assum derived from std::exception
}
return pDb_;
}

private:

Database* pDb_;
bool inited_;

DatabaseMgr() : pDb_(NULL), inited_(false) {};
DatabaseMgr(const DatabaseMgr& src);
~DatabaseMgr() { delete pDb_; };

DatabaseMgr& operator= (const DatabaseMgr& src);
}

Then, in my code I have something like this:

int main ()
{
try {

DatabaseMgr::instance().initialize("mydatabase.db");

// Some other stuff where I make calls to the database and everything
// is fine. So the following call works like a charm.
//
DatabaseMgr::instance().db()->executeQuery("SELECT * FROM Table");


}
catch (std::exception& exc) {

// Handle and exit with error.
return 1;
}

return 0;
}

The problem I was having is that when I built the application in a Release
configuration with optimizations, the DatabaseMgr::instance() call was
working
for the most part, but however, in some situations it will create a new
instance
and of course the call to db() will throw an exception because the Database
object is not initialized.

I tried a couple of things, but I finally resolved the problem by moving the
implementation of the instance() method to a .cpp so that it doesn't inline.

My question is, can a compiler generate multiple instances of an static
method?
Keep in mind that the keyword inline was not used, just that the
implementation
was inside of the class declaration. What does the standard says on this
aspect?
Is it just a bug in VC7.0?

Thanks,

--

Isaac Rodriguez
SW Engineer - Autodesk
----------------------------------------
There are 10 types of people.
Those who understand binary,
and those who don't.




[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
bitleo
Guest





PostPosted: Sat Dec 18, 2004 12:21 pm    Post subject: Re: Implementing static methods inside the class declaration Reply with quote



This is not a bug. This is what c++ is supposed to do.
A class static object is created the first time it is declared and
destroyed once at the termination of the program. There is exactly one
copy of a static class member. It belongs to the class, not the
object/instance. Same thing with the functions.
Good luck


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Kurt Krueckeberg
Guest





PostPosted: Sat Dec 18, 2004 12:25 pm    Post subject: Re: Implementing static methods inside the class declaration Reply with quote




Quote:
Hi,

Is this a bug in VC7.0, a bad programming practice, or both? I have a
singleton
class that is defined something like this:

class DatabaseMgr
{
public:

static DatabaseMgr& instance () {

static DatabaseMgr inst;
return inst;
}

void initialize (const String& filename) {

pDb_ = new Database(filename);
// and some other stuff.
inited = true;
}

Database* db () {

if( !inited_ ) {

throw MyException; // Assum derived from std::exception
}
return pDb_;
}

private:

Database* pDb_;
bool inited_;

DatabaseMgr() : pDb_(NULL), inited_(false) {};
DatabaseMgr(const DatabaseMgr& src);
~DatabaseMgr() { delete pDb_; };

DatabaseMgr& operator= (const DatabaseMgr& src);
}


Why not simplify the class and see if the bug goes away.

class Database {
public:
static Database& instance (const String& filename)
{
if (!instance_) {
instance_ = new Database(filename);
}
return *instance_;
}
private:
Database(const String&);
Database(const Database&);
DatabaseMgr& operator= (const DatabaseMgr& src);
static Database *instance_;
};

Database *Database::instance_ = 0;



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Allan W
Guest





PostPosted: Tue Dec 21, 2004 10:18 am    Post subject: Re: Implementing static methods inside the class declaration Reply with quote

If a function is implemented inside the class declaration, it IS
inline, even if that keyword is not present.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Isaac Rodriguez
Guest





PostPosted: Tue Dec 21, 2004 10:23 am    Post subject: Re: Implementing static methods inside the class declaration Reply with quote


"Kurt Krueckeberg" <kurtk (AT) pobox (DOT) com> wrote

Quote:

Hi,

Is this a bug in VC7.0, a bad programming practice, or both? I have a
singleton
class that is defined something like this:

class DatabaseMgr
{
public:

static DatabaseMgr& instance () {

static DatabaseMgr inst;
return inst;
}

void initialize (const String& filename) {

pDb_ = new Database(filename);
// and some other stuff.
inited = true;
}

Database* db () {

if( !inited_ ) {

throw MyException; // Assum derived from std::exception
}
return pDb_;
}

private:

Database* pDb_;
bool inited_;

DatabaseMgr() : pDb_(NULL), inited_(false) {};
DatabaseMgr(const DatabaseMgr& src);
~DatabaseMgr() { delete pDb_; };

DatabaseMgr& operator= (const DatabaseMgr& src);
}


Why not simplify the class and see if the bug goes away.

class Database {
public:
static Database& instance (const String& filename)
{
if (!instance_) {
instance_ = new Database(filename);
}
return *instance_;
}
private:
Database(const String&);
Database(const Database&);
DatabaseMgr& operator= (const DatabaseMgr& src);
static Database *instance_;
};

Database *Database::instance_ = 0;

I am not sure what are you trying to do here and why are you mixing the
classes Database and DatabaseMgr. The Database class comes from a 3rdParty
library and DatabaseMgr is a Singleton class that I implemented myself. I
can still check the pointer instead of having a boolean like you show. The
reason I didn't is because the first implementation of the class wasn't
going to use a pointer, and I guess I didn't realize when the implementation
chaged, but it still doesn't work.

I can accomplish the correct behavior by moving the implementation of
DatabaseMgr::instance() to a .cpp file and not inlining it, so my problem is
solved. What I would like to know if it is this the correct behavior or
there is a bug in the VC7.0 optimized code that is generated. The Debug
version does not present this problem at all and once I move the code to the
..cpp the problem disappears. I would like to know if this is the correct
behavior according to the standard and I got my understanding of static
members a little bit confused, or it is just a simple defect in the VC7.0
implementation.

Right now, I cannot check other compilers to see what the results are.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Isaac Rodriguez
Guest





PostPosted: Tue Dec 21, 2004 10:24 am    Post subject: Re: Implementing static methods inside the class declaration Reply with quote

If there is exactly one copy of a static class member, why it is creating
two copies of the static object there declared. If I understand you
correctly, it seems to me that it is a bug with the optimizations in VC7.0
that it is inlining the static instance() member function in some of the
calls; therefore creating more than one copy of the static variable inst_.

Thanks,

--

Isaac Rodriguez
SW Engineer - Autodesk
----------------------------------------
There are 10 types of people.
Those who understand binary,
and those who don't.


"bitleo" <bitleo (AT) gmail (DOT) com> wrote

Quote:
This is not a bug. This is what c++ is supposed to do.
A class static object is created the first time it is declared and
destroyed once at the termination of the program. There is exactly one
copy of a static class member. It belongs to the class, not the
object/instance. Same thing with the functions.
Good luck

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Isaac Rodriguez
Guest





PostPosted: Wed Dec 22, 2004 8:58 am    Post subject: Re: Implementing static methods inside the class declaration Reply with quote

So you mean that it will be inlined even if it is an static function? That
doesn't make much sense to me. Are you sure that the standard says something
like that?

Thanks,

--

Isaac Rodriguez
SW Engineer - Autodesk
----------------------------------------
There are 10 types of people.
Those who understand binary,
and those who don't.


"Allan W" <allan_w (AT) my-dejanews (DOT) com> wrote

Quote:
If a function is implemented inside the class declaration, it IS
inline, even if that keyword is not present.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Daniel Krügler (ne Spange
Guest





PostPosted: Wed Dec 22, 2004 9:05 am    Post subject: Re: Implementing static methods inside the class declaration Reply with quote

Hello Isaac Rodriguez,

Isaac Rodriguez schrieb:

Quote:
I can accomplish the correct behavior by moving the implementation of
DatabaseMgr::instance() to a .cpp file and not inlining it, so my problem is
solved. What I would like to know if it is this the correct behavior or
there is a bug in the VC7.0 optimized code that is generated. The Debug
version does not present this problem at all and once I move the code to the
.cpp the problem disappears. I would like to know if this is the correct
behavior according to the standard and I got my understanding of static
members a little bit confused, or it is just a simple defect in the VC7.0
implementation.

I can affirm, that I recently stumbled about a similar problem with

VC7.1 in release mode. Regrettably
it was not easy to break down (so that I could provide the VC developer
team with any valuable
information), but providing the definition of the static member function
in a separate translation unit
lead to the fix as you describe.

Greetings from Bremen,

Daniel Krügler


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Vladimir Marko
Guest





PostPosted: Thu Dec 23, 2004 3:30 pm    Post subject: Re: Implementing static methods inside the class declaration Reply with quote

Allan W wrote:
Quote:
If a function is implemented inside the class declaration, it IS
inline, even if that keyword is not present.

Right, that's 9.3/2. And for the actual problem:

9.3/6 A static local variable in a member function always
refers to the same object, whether or not the member function
is inline.

Though static member functions differ from non-static ones,
they _are_ member functions and thus they are covered by
9.3/6. On the other hand we do have a similar guarantee for
_extern_ inline functions in

7.1.2/4 ... A static local variable in an extern inline
function always refers to the same object. ...

So, if you happen to get two or more different addresses
from "std::cout << &DatabaseMgr::instance()" the compiler
is wrong.

If the program runs only a single thread the code should work.
If not search clc++m for threads about singletons in the
presence of threads, there are a lot of them.

Regards,
Vladimir Marko


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Isaac Rodriguez
Guest





PostPosted: Thu Dec 23, 2004 10:11 pm    Post subject: Re: Implementing static methods inside the class declaration Reply with quote


Quote:
I can affirm, that I recently stumbled about a similar problem with
VC7.1 in release mode. Regrettably
it was not easy to break down (so that I could provide the VC developer
team with any valuable
information), but providing the definition of the static member function
in a separate translation unit
lead to the fix as you describe.

Yes, it is hard to create a simple code sample that reproduces the problem
because the compiler doesn't inline it in every call, and I cannot send them
my production code as an example. I had some other similar code that was
behaving correctly, but I did the same thing and move the implementation to
..cpp files. I don't want the bug to reappear when least expected.

--

Isaac Rodriguez
SW Engineer - Autodesk
----------------------------------------
There are 10 types of people;
those who understand binary and those who don't.
There are 10 types of people.
Those who understand binary,
and those who don't.



[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.