473,386 Members | 1,860 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

static class member variables

I have a static class member variable as follows:

struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

int A::v; // define A::v in the cpp file
A::v will have external linkage and there will only be one instance of this
variable in the executable:

However, let's say I don't want to define the variable in the cpp file (eg.
it's a template class and I don't want users to have to define the
variable).
Is there anything wrong with defining it in a static member function which
returns a reference to the variable? Will there also always only be one copy
of the local static variable? Any other unforseen problems? Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v;
return v;
}
};

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #1
16 2949
Eric wrote:
I have a static class member variable as follows:

struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

int A::v; // define A::v in the cpp file
A::v will have external linkage and there will only be one instance of this
variable in the executable:

However, let's say I don't want to define the variable in the cpp file (eg.
it's a template class and I don't want users to have to define the
variable).
You could define the entire template in the header file.

template <typename X>
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

template <typename X>
int A::v; // define A::v in the header file

Is there anything wrong with defining it in a static member function which
returns a reference to the variable? Will there also always only be one copy
of the local static variable? Any other unforseen problems? Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v;
return v;
}
};

In theory, this will work as well, however, some linkers will violate
the "only one copy" rule when you start using DLL's.

Having said that, this is the ONLY way to guarentee the order of
construction in case you're constructing many inter-related objects
before calling main(), so it is a recomended practice.

Jul 22 '05 #2
On 17 Nov 2004 06:12:08 -0500, Eric <sh*****@yahoo.com> wrote:
I have a static class member variable as follows:

struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

int A::v; // define A::v in the cpp file
A::v will have external linkage and there will only be one instance of
this variable in the executable:

However, let's say I don't want to define the variable in the cpp file
(eg. it's a template class and I don't want users to have to define the
variable).
You can use a trick to place the static in *.h without getting multiple
simbol definitions linker error - place that static in a template base
class as follows:

template<int dummy> struct statics { static int v; };
template<int dummy> int statics<dummy>::v;

struct A : private statics<1234>
{
// Get/Set are the same as before
};
Is there anything wrong with defining it in a static member function
which returns a reference to the variable? Will there also always only
be one copy of the local static variable? Any other unforseen problems?
Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v;
return v;
}
};


Probably, you forgot static keyword here. The code as it is written now
returns a dangling reference to the already evaporated local variable. You
can fix it as:

static int& Get () { static int v; return v; }

--
Maxim Yegorushkin

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #3
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message news:<op**************@devlx007.ipcb.net>...

You can use a trick to place the static in *.h without getting multiple
simbol definitions linker error - place that static in a template base
class as follows:

template<int dummy> struct statics { static int v; };
template<int dummy> int statics<dummy>::v;

struct A : private statics<1234>
{
// Get/Set are the same as before
};


Just a slight tidy up:

template<int = 0> struct statics { static int v; };
template<int dummy> int statics<dummy>::v;

struct A : private statics<>
{
// Get/Set are the same as before
};

Is there anything wrong with defining it in a static member function
which returns a reference to the variable? Will there also always only
be one copy of the local static variable? Any other unforseen problems?
Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v; <------------------ missing int
return v;
}
};


Probably, you forgot static keyword here. The code as it is written now
returns a dangling reference to the already evaporated local variable. You
can fix it as:

static int& Get () { static int v; return v; }

Look again. The only mistake is a missing int on the line I marked
(which of course will compile on older compilers, since the int was
implied in pre-standard C++). (Also, Get should probably return by
value, but that's a design point rather than an error.)
James

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #4
Hello Maxim Yegorushkin,

Maxim Yegorushkin schrieb:
On 17 Nov 2004 06:12:08 -0500, Eric <sh*****@yahoo.com> wrote:

Is there anything wrong with defining it in a static member function
which returns a reference to the variable? Will there also always only
be one copy of the local static variable? Any other unforseen problems?
Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v;
return v;
}
};


Probably, you forgot static keyword here. The code as it is written now
returns a dangling reference to the already evaporated local variable. You
can fix it as:

static int& Get () { static int v; return v; }

Your description is somewhat misleading. I think the actual error, the
OP made was, that its declaration
of the local static in v misses a type. This looks like an MSVC
compiler: Its a real **shame** that even MSVC7.1
does allow implicit int declarations!! (In this case the compiler was
taking the right "guess", but what about
the next time??).

Furtheron it seems reasonable that the OP's Get function signature
should be changed to

struct A
{
...
static int Get () { return v(); }
...
};

because otherwise The Set function does not make very much sense...

Last but not least: Your proposal to use the template helper class is a very
cool idea, Maxim!

Greetings from Bremen,

Daniel


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

Jul 22 '05 #5
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message news:<op**************@devlx007.ipcb.net>...
On 17 Nov 2004 06:12:08 -0500, Eric <sh*****@yahoo.com> wrote:
...
Is there anything wrong with defining it in a static member function
which returns a reference to the variable? Will there also always only
be one copy of the local static variable? Any other unforseen problems?
Thanks in
advance for any comments.

struct A
{
static void Set (int i) { v() = i; }
static int& Get () { return v(); }
static int& v()
{
static v;
return v;
}
};
Probably, you forgot static keyword here.


Where?
The code as it is written now returns a dangling reference to the already
evaporated local variable. You can fix it as:

static int& Get () { static int v; return v; }


static int& v () { static int v; return v; } // ?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #6
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message
news:<op**************@devlx007.ipcb.net>...
On 17 Nov 2004 06:12:08 -0500, Eric <sh*****@yahoo.com> wrote:
I have a static class member variable as follows:

struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

int A::v; // define A::v in the cpp file
A::v will have external linkage and there will only be one instance of
this variable in the executable:

However, let's say I don't want to define the variable in the cpp file
(eg. it's a template class and I don't want users to have to define the
variable).

Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};

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

Jul 22 '05 #7
On 19 Nov 2004 07:59:16 -0500, Daniel Krügler (ne Spangenberg)
<ds*@bdal.de> wrote:

[]
Your description is somewhat misleading.
I agree, that was not a well thought answer.
Last but not least: Your proposal to use the template helper class is a
very cool idea, Maxim!


I've stolen the idea from Dinkum STL implementation where it's used for
std::ios_base::flags (in, out, ate, etc.).

--
Maxim Yegorushkin

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

"Renjith Mohan" <re**********@hotmail.com> schrieb im Newsbeitrag
news:cd**************************@posting.google.c om...
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message
news:<op**************@devlx007.ipcb.net>...
On 17 Nov 2004 06:12:08 -0500, Eric <sh*****@yahoo.com> wrote:
I have a static class member variable as follows:

struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
static int v;
};

int A::v; // define A::v in the cpp file
A::v will have external linkage and there will only be one instance of
this variable in the executable:

However, let's say I don't want to define the variable in the cpp file
(eg. it's a template class and I don't want users to have to define the variable).

Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};


Not a clever solution.

v is not tied to class A by any means and can be accessed directly without
any A object / operator ::.
Also, try to use this with multiple translation units, each changing and
reading v (via the functions provided in A). Surprise, surprise (at least
when the semantic of the OP is intended).
Thomas

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #9
Renjith Mohan wrote:
Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};


An unnamed namespace in a header file? Each of the translation units
that includes it will have its own copy of v, then. :(

--
Seungbeom Kim

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

Jul 22 '05 #10
Renjith Mohan wrote:
Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};


I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here. The exact meaning of 'return v' is different in every
TU because of the fact that an unnamed namespace does have a name, though
hidden and distinct for every TU.

Aside from (possible) ODR violation, there are other problems. This places
a distinct instance of an object from the unnamed namespace in every TU
that includes the header with the unnamed namespace, what results in quite
different semantics because now every TU operates on an own instance of v.

--
Maxim Yegorushkin

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

"Maxim Yegorushkin" <e-*****@yandex.ru> schrieb im Newsbeitrag
news:opshq9w3y9ti5cme@wkcg6rirwp...
Renjith Mohan wrote:
Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};
I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here.

Don't think so. Since v has internal linkage....


Aside from (possible) ODR violation, there are other problems. This places
a distinct instance of an object from the unnamed namespace in every TU
that includes the header with the unnamed namespace, what results in quite
different semantics because now every TU operates on an own instance of v.


That IS a problem.
Thomas

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

Jul 22 '05 #12
"Thomas Mang" <no****@nospam.invalid> wrote...
"Maxim Yegorushkin" <e-*****@yandex.ru> schrieb im Newsbeitrag
news:opshq9w3y9ti5cme@wkcg6rirwp...
Renjith Mohan wrote:
> Another solution is to use an unnamed namespace which is semantically
> equivalent to internal linkage and is a mcuh more simple and elegant
> solution.
> Thus in a header file you can do this.
> namespace
> {
> int v;
> }
> struct A
> {
> static void Set (int i) { v = i; }
> static int& Get () { return v; }
>
> };
I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here.

Don't think so. Since v has internal linkage....


A big misconception. 'v' has _external_ linkage, but it doesn't matter.
Every file that includes that header has its own 'v', since its name has
the name of the anonymous namespace added to it.
[..the other problem is correctly identified..]


V
Jul 22 '05 #13
In article <41***********************@usenet.univie.ac.at>, Thomas Mang
<no****@nospam.invalid> writes
"Maxim Yegorushkin" <e-*****@yandex.ru> schrieb im Newsbeitrag
news:opshq9w3y9ti5cme@wkcg6rirwp...
Renjith Mohan wrote:
> Another solution is to use an unnamed namespace which is semantically
> equivalent to internal linkage and is a mcuh more simple and elegant
> solution.
> Thus in a header file you can do this.
> namespace
> {
> int v;
> }
> struct A
> {
> static void Set (int i) { v = i; }
> static int& Get () { return v; }
>
> };


I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here.

Don't think so. Since v has internal linkage....


It doesn't, it has external linkage but with an unutterable name.
However that is not really relevant because there is a potential ODR
violation which ever way you take it. If the above header file is
included in more than one TU the definition of struct A will be an ODR
issue.
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #14
"Maxim Yegorushkin" <e-*****@yandex.ru> wrote in message
news:<opshq9w3y9ti5cme@wkcg6rirwp>...
Renjith Mohan wrote:
Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }

};


I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here. The exact meaning of 'return v' is different in every
TU because of the fact that an unnamed namespace does have a name, though
hidden and distinct for every TU.

Aside from (possible) ODR violation, there are other problems. This places
a distinct instance of an object from the unnamed namespace in every TU
that includes the header with the unnamed namespace, what results in quite
different semantics because now every TU operates on an own instance of v.

I understand my misconception. Thanks for pointing this out. I seem to
have been over enthusiastic about the clause 7.3.1.1 - Unnamed
namespaces para 2 which says something like this
"The use of the static keyword is deprecated when declaring objects in
a namespace scope (see annex depr); the unnamed-namespace provides a
superior alternative."

As has been pointed out this applies to "namespace scope" members only
and even with such variables this must be used with caution as the
generated namespace name(for the unnamed namespace) in each TU is
implementation dependent which may create binary differences of the
executable which is beyond programmers control.

But a doubt remains; since the standard does recommend it for
"namespace scope" variables, does it violate ODR for such variables?.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #15
Thomas Mang wrote:
"Maxim Yegorushkin" <e-*****@yandex.ru> schrieb im Newsbeitrag news:opshq9w3y9ti5cme@wkcg6rirwp...
Renjith Mohan wrote:
Another solution is to use an unnamed namespace which is semantically
equivalent to internal linkage and is a mcuh more simple and elegant
solution.
Thus in a header file you can do this.
namespace
{
int v;
}
struct A
{
static void Set (int i) { v = i; }
static int& Get () { return v; }
};


I strongly disagree. I am not sure, but it seems to me, that you've got
ODR violation here.


Don't think so. Since v has internal linkage....


No, v does not have internal linkage. Things inside the unnamed
namespace have external linkage. They just have a name that is known
only to the current translation unit, making them inaccessible from
other translation units. The ultimate effect is very similar to making
v static, but there are some subtle differences that must be understood.

The one-definition rule (ODR) violation is not with v, it is with A::Set
and A::Get. Within each translation unit, A::Set and A::Get refer to
the v that is unique to that translation unit. Therefore, A::Set and
A::Get are not the same in all translation units, which is not allowed.

--
David Olsen
qg********@yahoo.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 22 '05 #16
re**********@hotmail.com (Renjith Mohan) wrote in message
news:<cd**************************@posting.google. com>...

But a doubt remains; since the standard does recommend it for
"namespace scope" variables, does it violate ODR for such variables?.


In this context, you get ODR violations using either (deprecated)
namespace scope statics or a nameless namespace. Using a nameless
namespace doesn't make it any more wrong :-)

Point of interest: boost::bind uses a nameless namespace in a header
to define _1, _2 etc. (the parameter placeholders). I've yet to get a
grip on the pros and cons of this - not that it's something you have
to understand to use bind itself.
James

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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

29
by: Alexander Mahr | last post by:
Dear Newsgroup, I'm somehow confused with the usage of the static keyword. I can see two function of the keyword static in conjunction with a data member of a class. 1. The data member...
11
by: Roger Leigh | last post by:
The C++ book I have to hand (Liberty and Horvath, Teach yourself C++ for Linux in 21 Days--I know there are better) states that "static member functions cannot access any non-static member...
25
by: Sahil Malik [MVP] | last post by:
So here's a rather simple question. Say in an ASP.NET application, I wish to share common constants as static variables in global.asax (I know there's web.config bla bla .. but lets just say I...
11
by: Kevin Prichard | last post by:
Hi all, I've recently been following the object-oriented techiques discussed here and have been testing them for use in a web application. There is problem that I'd like to discuss with you...
1
by: mangalalei | last post by:
A static data member can be of the same class type as that of which it is a member. A nonstatic data member is restricted to being declared as a pointer or a reference to an object of its class. ...
5
by: mast2as | last post by:
Hi guys Here's the class I try to compile (see below). By itself when I have a test.cc file for example that creates an object which is an instance of the class SpectralProfile, it compiles...
55
by: Zytan | last post by:
I see that static is more restricted in C# than in C++. It appears usable only on classes and methods, and data members, but cannot be created within a method itself. Surely this is possible in...
9
by: Jess | last post by:
Hello, I was told that if I declare a static class constant like this: class A{ static const int x = 10; }; then the above statement is a declaration rather than a definition. As I've...
17
by: Juha Nieminen | last post by:
As we know, the keyword "inline" is a bit misleading because its meaning has changed in practice. In most modern compilers it has completely lost its meaning of "a hint for the compiler to inline...
4
by: aaragon | last post by:
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...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.