This is the mail archive of the
cygwin-developers@cygwin.com
mailing list for the Cygwin project.
Re: gcc4 and local statics
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