Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Static local variable in an inline static member function

564 views
Skip to first unread message

lhy...@gmail.com

unread,
Oct 25, 2007, 8:23:57 PM10/25/07
to
Hello-

I have a question about the following construction:

struct A {
static A& get() {
static A a;
return a;
}
};

(I'm not really trying to implement a singleton or anything like that,
my question is just about this particular code.)

If this appears in a header file that is then included in multiple
translation units, is it supposed to be guaranteed that there is only
one copy of the static A object? That seems difficult for the compiler/
linker to insure, since multiple copies of the function get() will be
generated, but it's probably what the code intends, right? I'm asking
because I know of definite examples where a particular version of g++
breaks on similar code.

Thanks...

-Lewis


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

Hyman Rosen

unread,
Oct 26, 2007, 4:27:48 AM10/26/07
to
lhy...@princeton.edu wrote:
> struct A { static A& get() { static A a; return a; } };
>
> If this appears in a header file that is then included in multiple
> translation units, is it supposed to be guaranteed that there is only
> one copy of the static A object?

Yes.

> That seems difficult for the compiler/linker to insure

That's why compiler/linker writers get those big bucks :-)

Generally the way this works is that a copy of the object
and function gets compiled into every compilation unit that
includes it, marked in a special way that tells the linker
to expect multiple identical copies. The linker then just
incorporates a single copy into the final executable. In a
high-quality implementation, the linker will complain if it
finds differences in the various copies.

Sid

unread,
Oct 26, 2007, 4:35:28 AM10/26/07
to
AFAIK a struct is exactly the same as a class, with the exception that
members are private by defualt in a class and public by default in a
struct. That being said, I would assume that you would have to make a
definition of the static members in a CPP file. I haven't tried this
though.

- Sid

Daniel Krügler

unread,
Oct 26, 2007, 5:06:53 AM10/26/07
to
On 26 Okt., 02:23, "lhy...@princeton.edu" <lhy...@gmail.com> wrote:
> struct A {
> static A& get() {
> static A a;
> return a;
> }
>
> };

OK, this is Meyers singleton.

[..]

> If this appears in a header file that is then included in multiple
> translation units, is it supposed to be guaranteed that there is only
> one copy of the static A object?

Yes, this is guaranteed, see [dcl.fct.spec]/4:

"[..] An inline function with external linkage shall have the same
address in all translation units. A static local variable in an extern
inline function always refers to the same object. A string literal in an
extern inline function is the same object in different translation units."

> That seems difficult for the compiler/
> linker to insure, since multiple copies of the function get() will be
> generated, but it's probably what the code intends, right? I'm asking
> because I know of definite examples where a particular version of g++
> breaks on similar code.

This particular version of g++ is not alone, see e.g. a case description,
where the MS VS2003 compiler can't handle this properly:

http://www.codeproject.com/useritems/VC2003MeyersSingletonBug.asp

Greetings from Bremen,

Daniel Krügler

Martin Bonner

unread,
Oct 26, 2007, 10:23:54 PM10/26/07
to
On Oct 26, 9:35 am, Sid <siddharth.he...@gmail.com> wrote:
> AFAIK a struct is exactly the same as a class, with the exception that
> members are private by defualt in a class and public by default in a
> struct.

Absolutely correct.

> That being said, I would assume that you would have to make a
> definition of the static members in a CPP file.

Static member functions (like any other sort of function) can either
be defined in a cpp file, or (if they are marked as inline) in a
header file. In this case, the only member is "get()", and that is
implicitly marked as inline by being defined inside the class/struct.

Static member variables must be defined in a single CPP file (unless
they are integral and initialized with a constant value). However,
there aren't any static member variables in this example.


> I haven't tried this though.

The problem is that get() is such a simple function that the
implementation may be tempted to inline it. However if it does so, it
must ensure that there is only one instance of the static variable a.

To the OP: The code as written is perfectly valid according to the
standard; however it is the sort of corner case that is more likely
than most to provoke compiler bugs. If you can move the definition of
get() into a cpp file, it's much more likely to work.

Vinu

unread,
Oct 26, 2007, 10:31:43 PM10/26/07
to
On Oct 26, 10:27 am, Hyman Rosen <hyro...@mail.com> wrote:
> lhy...@princeton.edu wrote:
> > struct A { static A& get() { static A a; return a; } };
>
> > If this appears in a header file that is then included in multiple
> > translation units, is it supposed to be guaranteed that there is only
> > one copy of the static A object?
>
> Yes.
>
> > That seems difficult for the compiler/linker to insure
>
> That's why compiler/linker writers get those big bucks :-)
>
> Generally the way this works is that a copy of the object
> and function gets compiled into every compilation unit that
> includes it, marked in a special way that tells the linker
> to expect multiple identical copies. The linker then just
> incorporates a single copy into the final executable. In a
> high-quality implementation, the linker will complain if it
> finds differences in the various copies.
>

But what if shared library is being built instead of an executable.
And more than 1 shared library use this static object and ultimately
all the shared libraries are used in a single process.
So now, does the process have only one instance of this object. I dont
think so.

The way i think this works is that its unique in each translation
unit. And so there is one copy in each transaltion unit you include.
Something akin to how the static keyword works in C.
Anyways this is what i think????

{ quoted clc++m banner removed - please do it yourself -mod }

Hyman Rosen

unread,
Oct 28, 2007, 3:23:16 AM10/28/07
to
Vinu wrote:
> But what if shared library is being built instead of an executable.

Now your are getting deep into implementation-level issues that the
standard doesn't address. A high-quality implementation will maintain
the proper single-instance behavior even across shared libraries, but
for details, you have to consult your vendor's documentation.

jtorj...@yahoo.com

unread,
Nov 1, 2007, 5:28:00 PM11/1/07
to
On 26 Oct, 11:06, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> On 26 Okt., 02:23, "lhy...@princeton.edu" <lhy...@gmail.com> wrote:
>
> > struct A {
> > static A& get() {
> > static A a;
> > return a;
> > }
>
> > };
>
> OK, this is Meyers singleton.
>
> [..]
>
> > If this appears in a header file that is then included in multiple
> > translation units, is it supposed to be guaranteed that there is only
> > one copy of the static A object?
>
> Yes, this is guaranteed, see [dcl.fct.spec]/4:
>
> "[..] An inline function with external linkage shall have the same
> address in all translation units. A static local variable in an extern
> inline function always refers to the same object. A string literal in an
> extern inline function is the same object in different translation units."
>
> This particular version of g++ is not alone, see e.g. a case description,
> where the MS VS2003 compiler can't handle this properly:
>
> http://www.codeproject.com/useritems/VC2003MeyersSingletonBug.asp
>

Indeed so ;) I've spent a few hours dealing with exactly this
situation - and ended up placing the implementation in the source
file. From my experience, it's better to place the implementation in
the source file. But then again, it depends on what compiler you'll be
using. If the latest (VS2005/g++ 4.1+) then you're ok.

Best,
John


--
http://John.Torjo.com -- C++ expert
... call me only if you want things done right

0 new messages