Topic: statics declared inside inline member fns


Author: Gary Mussar <mussar@nortel.ca>
Date: 1997/07/18
Raw View
mseitz@meridian-data.com wrote:
>
> In article <rf5lo3fmh6y.fsf@vx.cit.alcatel.fr>, James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
> >According to the draft, inline functions have exactly the same semantics
> >as the non-inline variant.  So the static variable must be shared by all
> >instances of the function.
>
> I interpret the draft differently.  From my reading of section 7.1.2.4
> (Declarations:Specifiers:Function Specifiers), it appears that static
> variables declared in an ordinary inline function are local to the translation
> unit.  That means each translation unit will have its own instance of the
> static variable.  However, it goes on to say that if an inline function is
> declared as "extern", then the local static will be shared by all instances of
> the function.

I was always under the impression that adding the keyword inline to
a function should not change the behaviour of the function. This
interpretation means that the behaviour of function scoped statics
does change. This sounds like a serious inconsistency that will
cause significant problems and be very difficult to debug.

--
Gary Mussar <mussar@nortel.ca>   Phone: (613) 763-4937
Nortel                           FAX:   (613) 763-9406
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Steve Clamage <stephen.clamage@eng.sun.com>
Date: 1997/07/21
Raw View
mseitz@meridian-data.com wrote:
>
> In article <rf5lo3fmh6y.fsf@vx.cit.alcatel.fr>, James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
> >According to the draft, inline functions have exactly the same semantics
> >as the non-inline variant.  So the static variable must be shared by all
> >instances of the function.
>
> I interpret the draft differently.  From my reading of section 7.1.2.4
> (Declarations:Specifiers:Function Specifiers), it appears that static
> variables declared in an ordinary inline function are local to the translation
> unit.  That means each translation unit will have its own instance of the
> static variable.  However, it goes on to say that if an inline function is
> declared as "extern", then the local static will be shared by all instances of
> the function.
>
> That interpretation is confirmed in MORE EFFECTIVE C++, fourth printing,
> p.134.

The current draft does not have a section 7.1.2.4; section 7.1.2
"Function specifiers" does not have any subsections.

I don't see any way to interpet section 7.1.2 to get the semantics
you expect, except for inline functions explicitly declared
static. In fact, paragraph 4 of 7.1.2 says in a note:

"[Note: a static local variable in an extern inline function always
refers to the same object.]"

The ARM said inline functions had static linkage, but didn't say
what the linkage of inline class member functions was.

For some time now, the draft standard has said that declaring a
function inline does not affect its linkage, and that functions
have external linkage unless declared static. If a function has
external linkage, there is only one copy in the entire program of
any of its local static objects.

Existing books and compilers may have been written to earlier
versions of the draft, and thus might not correspond to the
current version. This aspect of inline functions is not going
to change, given the schedule for publishing a final standard.

--
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/07/23
Raw View
mseitz@meridian-data.com writes:

|>  In article <rf5lo3fmh6y.fsf@vx.cit.alcatel.fr>, James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
|>  >According to the draft, inline functions have exactly the same semantics
|>  >as the non-inline variant.  So the static variable must be shared by all
|>  >instances of the function.
|>
|>  I interpret the draft differently.  From my reading of section 7.1.2.4
|>  (Declarations:Specifiers:Function Specifiers), it appears that static
|>  variables declared in an ordinary inline function are local to the translation
|>  unit.  That means each translation unit will have its own instance of the
|>  static variable.  However, it goes on to say that if an inline function is
|>  declared as "extern", then the local static will be shared by all instances of
|>  the function.

Where does it say that?  I find nothing in section 7.1.2 which gives
inline functions different semantics than any other function.  The only
difference I see is how the function is defined: a non-inline function
must be defined exactly once, whereas an inline function must be defined
in every translation unit which uses it; all definitions must be the
same.  There is even a note to the effect that in "extern" inline
functions (presumably, "inline functions with external linkage"), there
must be only one copy of the local static.

Don't forget that the default linkage of a function is external -- you
have to explicitly specify "static" for a function not to have external
linkage.  And of course, if you do specify static, then there is a
different function in each translation unit, so it is normal that they
have different copies of the variable.

|>  That interpretation is confirmed in MORE EFFECTIVE C++, fourth printing,
|>  p.134.

That's because the above rule is a recent change, which occured *after*
the book was written.  In the ARM (and in earlier drafts), a non-member
inline function was implicitly static.

In practice (as opposed to what the standard says), I would avoid static
variables in inline functions at present.  Most current compilers
probably still consider a non-member inline function as being implicitly
static.  In fact, most compilers probably generate a member inline
function as if it had static linkage, although there has never been any
such thing in C++ as a member function with other than external linkage.

--
James Kanze   home:   kanze@gabi-soft.fr       +33 (0)1 39 55 85 62
              office: kanze@vx.cit.alcatel.fr  +33 (0)1 69 63 14 54
GABI Software, 22 rue Jacques-Lemercier, F-78000 Versailles, France
           -- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Christian Millour <chris161@club-internet.fr>
Date: 1997/07/09
Raw View
Hi all.

are statics declared within inline member functions shared
across compilation units ? not shared ? is this specified ?
implementation dependant ? undefined ? I couldn't find
anything in CD2.

for example, given

foo.hh:
#ifndef foo_H
class foo {
  static int & x() { static int x; return x; }
};
#endif /* foo_H */

assuming a [draft-] conforming compiler, can I count on
the x declared in foo::x() to be shared among all translation
units that invoke foo::x() ? or unshared ? neither ? depends ?

TIA.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/07/10
Raw View
Christian Millour <chris161@club-internet.fr> writes:

>are statics declared within inline member functions shared
>across compilation units ?

Yes, they are shared.

>I couldn't find anything in CD2.

The relevent stuff is the ODR, at the end of 3.2 [basic.def.odr]
paragraph 5: "... the program shall behave as if there is a single
definition ...".

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Ian Haggard <ian@shellus.com>
Date: 1997/07/10
Raw View
> are statics declared within inline member functions shared
> across compilation units ? not shared ? is this specified ?
> implementation dependant ? undefined ? I couldn't find
> anything in CD2.
According to the standard, statics declared within inline member
functions are shared across compilation units.  The reference for this
is in section 7.1.2 paragraph 4 of the December '96 Draft:
> [Note: a static local
>   variable in an extern  inline  function  always  refers  to  the  same
>   object.  ]
BTW in this quote, "extern inline" means an inline function which has
external linkage (i.e. one that is not declared static).

But I wouldn't rely on your compiler behaving like that.  In fact, I
recently tested out gcc 2.7.2.2 to see what it did, and its' behavior
was almost exactly the opposite -- a static local variable in an inline
function is not shared across compilation units.  However, if the inline
function is a template and optimization is not turned on, the variable
IS shared (ulp!).

But you can still 'fake' a having a static in an inline function using
tricks which are variations on this theme:

inline.h:
template<class T>
class initialize_global_on_use {
  T* t;
public:
  ~initialize_global_on_use() { delete t; }
  bool uninitialized() const { return !t; }
  T& object() { if ( uninitialized() ) t=new T; return *t; }
};

extern initialize_global_on_use<int> var;

inline int count_calls()
{ if ( var.uninitialized() ) var.object()=0; return ++var.object(); }

inline.cc:
initialize_global_on_use<int> var;

Note that this does require you to put var in a .cc file somewhere.  To
do the same thing for a template function requires you to have or create
a template class with a static initialize_global_on_use<T> member
variable in it and then access that variable from your function.  Ugly,
but it works.
--
Ian Haggard  ||  ian@shellus.com (work)  ||  IanHaggard@juno.com (home)
GNU/Linux -- "Oh, no, Mr Bill!" || #define employer_opinion !my_opinion
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Steve Clamage <stephen.clamage@Eng.Sun.COM>
Date: 1997/07/10
Raw View
Christian Millour wrote:
>
> are statics declared within inline member functions shared
> across compilation units ? not shared ? is this specified ?
> implementation dependant ? undefined ? I couldn't find
> anything in CD2.

>From 9.3 "Member functions":

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

--
Steve Clamage, stephen.clamage@eng.sun.com
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Alexandre Oliva <oliva@dcc.unicamp.br>
Date: 1997/07/10
Raw View
Christian Millour writes:

> are statics declared within inline member functions shared
> across compilation units ?

>From my interpretation of the CD2, they should be shared as long as
the enclosing class has external linkage.  [basic.link] says that a
member function of a class has external linkage if the name of the
class has external linkage, and [dcl.fct.spec] says that `a static
local variable in an extern inline function always refers to the same
object'.  The only doubt is whether `extern inline function' means an
inline function with external linkage or a function declared in
namespace scope with both extern and inline specifiers.

--
Alexandre Oliva
mailto:oliva@dcc.unicamp.br mailto:aoliva@acm.org
Universidade Estadual de Campinas, SP, Brasil
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: James Kanze <james-albert.kanze@vx.cit.alcatel.fr>
Date: 1997/07/11
Raw View
Christian Millour <chris161@club-internet.fr> writes:

|>  are statics declared within inline member functions shared
|>  across compilation units ? not shared ? is this specified ?
|>  implementation dependant ? undefined ? I couldn't find
|>  anything in CD2.

According to the draft, inline functions have exactly the same semantics
as the non-inline variant.  So the static variable must be shared by all
instances of the function.  (Strictly speaking: the visible behavior of
the program must be the same as if the function were not inline.)

In practice, I think that a lot of compilers still get this wrong
(although I could be wrong -- it's been a while since I checked).

--
James Kanze      home:     kanze@gabi-soft.fr        +33 (0)1 39 55 85 62
                 office:   kanze@vx.cit.alcatel.fr   +33 (0)1 69 63 14 54
GABI Software, Sarl., 22 rue Jacques-Lemercier, F-78000 Versailles France
            -- Conseils en informatique industrielle --
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: mseitz@meridian-data.com
Date: 1997/07/16
Raw View
In article <rf5lo3fmh6y.fsf@vx.cit.alcatel.fr>, James Kanze <james-albert.kanze@vx.cit.alcatel.fr> wrote:
>According to the draft, inline functions have exactly the same semantics
>as the non-inline variant.  So the static variable must be shared by all
>instances of the function.

I interpret the draft differently.  From my reading of section 7.1.2.4
(Declarations:Specifiers:Function Specifiers), it appears that static
variables declared in an ordinary inline function are local to the translation
unit.  That means each translation unit will have its own instance of the
static variable.  However, it goes on to say that if an inline function is
declared as "extern", then the local static will be shared by all instances of
the function.

That interpretation is confirmed in MORE EFFECTIVE C++, fourth printing,
p.134.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]