gcc4 and local statics

Christopher Faylor me@cgf.cx
Wed May 18 23:24:00 GMT 2005


On Wed, May 18, 2005 at 02:39:56PM -0700, Brian Dessent wrote:
>Christopher Faylor wrote:
>
>> It seems like static is being used like this in 28 different cases.  It
>> shouldn't be a big problem to audit the usage here and see if we really
>> need a gcc4-only option, with all of the headaches that will introduce
>> to the Makefile.
>> 
>> In the case of granularity, I think I'd actually opt for just making it
>> an automatic variable rather than a static variable.  There doesn't seem
>> to be any reason to ever initialize granularity unless mmap64 is used,
>> and the call is pretty cheap.  I'm not even sure how granularity is
>> supposed to be initialized when it is being set to the value of a
>> function.  Is it only supposed to call the function once and once-only?
>> If so, that would imply logic to avoid calling getshmlba more than once
>> which almost negates the overhead of just calling getshmlba every time.
>
>If you look at the patch in the PR, what it's actually doing is emitting
>the following (pseudocode) for the static local object:
>
>   static <type> guard;
>   if (!guard.first_byte) {
>     if (__cxa_guard_acquire (&guard)) {
>       bool flag = false;
>       try {
>         // Do initialization.
>         flag = true; __cxa_guard_release (&guard);
>         // Register variable for destruction at end of program.
>       } catch {
>         if (!flag) __cxa_guard_abort (&guard);
>       }
>   }
>
>It allocates this guard variable which itself is static and starts out
>at 0, and iff initialization was successful it sets guard to 1 so that
>all of this is skipped next time.  In this case granularity's
>initializer is just calling getshmlba(), and this will only happen once;
>however 'guard' will be checked each time.

I just remembered that I have gcc 4.1 installed on my computer so I took
a look at the assembly language from this function:

  int
  foo (int b)
  {
    static int a = 27;
    return a + b;
  }

This stores a in a static location, initialized to 27.  It doesn't produce
any special code for thread safety.  This actually makes some sense when
assigning a constant to a static.  The constant isn't going to change and
the static is always going to occupy one place in memory.

This, OTOH, did produce the type of code that you mentioned:

  int bar ();
  int
  foo (int b)
  {
    static int a = bar ();
    return a + b;
  }

and that also makes sense since you can only initialize a on the first visit
to foo.

You probably knew all this already but I'm relieved to find out that I
wasn't writing inefficient code all of these years.

There is still the issue of real class constructors, of course.  Those
are a little harder to track down than the use of ' static int foo =
something;' but I wouldn't expect them to be very prevalent in cygwin
either.

cgf



More information about the Cygwin-developers mailing list