 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Eric Guest
|
Posted: Wed Nov 17, 2004 11:12 am Post subject: 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! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Thu Nov 18, 2004 12:09 am Post subject: Re: static class member variables |
|
|
On 17 Nov 2004 06:12:08 -0500, Eric <shoongi (AT) yahoo (DOT) com> wrote:
| Quote: | 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
};
| Quote: | 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! ]
|
|
| Back to top |
|
 |
James Hopkin Guest
|
Posted: Fri Nov 19, 2004 12:50 pm Post subject: Re: static class member variables |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote
| Quote: |
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
template<int dummy> int statics<dummy>::v;
struct A : private statics<>
{
// Get/Set are the same as before
};
| Quote: | 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! ]
|
|
| Back to top |
|
 |
Daniel Krügler (ne Spange Guest
|
Posted: Fri Nov 19, 2004 12:59 pm Post subject: Re: static class member variables |
|
|
Hello Maxim Yegorushkin,
Maxim Yegorushkin schrieb:
| Quote: | On 17 Nov 2004 06:12:08 -0500, Eric <shoongi (AT) yahoo (DOT) 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! ]
|
|
| Back to top |
|
 |
Tokyo Tomy Guest
|
Posted: Fri Nov 19, 2004 3:24 pm Post subject: Re: static class member variables |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote
| Quote: | On 17 Nov 2004 06:12:08 -0500, Eric <shoongi (AT) yahoo (DOT) 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?
| Quote: | 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! ]
|
|
| Back to top |
|
 |
Renjith Mohan Guest
|
Posted: Fri Nov 19, 2004 4:01 pm Post subject: Re: static class member variables |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote
| Quote: | On 17 Nov 2004 06:12:08 -0500, Eric <shoongi (AT) yahoo (DOT) 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! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Fri Nov 19, 2004 4:51 pm Post subject: Re: static class member variables |
|
|
On 19 Nov 2004 07:59:16 -0500, Daniel Krügler (ne Spangenberg)
<dsp (AT) bdal (DOT) de> wrote:
[]
| Quote: | Your description is somewhat misleading.
|
I agree, that was not a well thought answer.
| Quote: | 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! ]
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Sat Nov 20, 2004 10:17 am Post subject: Re: static class member variables |
|
|
"Renjith Mohan" <renjithmohan (AT) hotmail (DOT) com> schrieb im Newsbeitrag
news:cd7223bc.0411180707.4fb20450 (AT) posting (DOT) google.com...
| Quote: | "Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote in message
news:<opshlwtry2ti5cme (AT) devlx007 (DOT) ipcb.net>...
On 17 Nov 2004 06:12:08 -0500, Eric <shoongi (AT) yahoo (DOT) 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! ]
|
|
| Back to top |
|
 |
Seungbeom Kim Guest
|
Posted: Sat Nov 20, 2004 4:23 pm Post subject: Re: static class member variables |
|
|
Renjith Mohan wrote:
| Quote: | 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! ]
|
|
| Back to top |
|
 |
Maxim Yegorushkin Guest
|
Posted: Sat Nov 20, 2004 6:19 pm Post subject: Re: static class member variables |
|
|
Renjith Mohan wrote:
| Quote: | 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! ]
|
|
| Back to top |
|
 |
Thomas Mang Guest
|
Posted: Sun Nov 21, 2004 5:00 am Post subject: Re: static class member variables |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opshq9w3y9ti5cme (AT) wkcg6rirwp (DOT) ..
| Quote: | 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....
| Quote: |
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! ]
|
|
| Back to top |
|
 |
Francis Glassborow Guest
|
Posted: Sun Nov 21, 2004 11:10 pm Post subject: Re: static class member variables |
|
|
In article <419fcbdb$0$24064$3b214f66 (AT) usenet (DOT) univie.ac.at>, Thomas Mang
<nospam (AT) nospam (DOT) invalid> writes
| Quote: | "Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag
news:opshq9w3y9ti5cme (AT) wkcg6rirwp (DOT) ..
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! ]
|
|
| Back to top |
|
 |
Renjith Mohan Guest
|
Posted: Sun Nov 21, 2004 11:16 pm Post subject: Re: static class member variables |
|
|
"Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> wrote
| Quote: | 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! ]
|
|
| Back to top |
|
 |
David Olsen Guest
|
Posted: Sun Nov 21, 2004 11:30 pm Post subject: Re: static class member variables |
|
|
Thomas Mang wrote:
| Quote: | "Maxim Yegorushkin" <e-maxim (AT) yandex (DOT) ru> schrieb im Newsbeitrag news:opshq9w3y9ti5cme (AT) wkcg6rirwp (DOT) ..
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
[email]qg4h9ykc5m (AT) yahoo (DOT) com[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
James Hopkin Guest
|
Posted: Mon Nov 22, 2004 9:37 pm Post subject: Re: static class member variables |
|
|
[email]renjithmohan (AT) hotmail (DOT) com[/email] (Renjith Mohan) wrote in message
news:<cd7223bc.0411210606.50c8d68a (AT) posting (DOT) google.com>...
| Quote: |
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! ]
|
|
| Back to top |
|
 |
|
|
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
|
|