Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #17326 > unrolled thread

global/static variables & loops

Started byRob Janecek <robs@invalid.com>
First post2012-02-14 19:56 +0000
Last post2012-02-16 03:17 -0800
Articles 20 on this page of 64 — 18 participants

Back to article view | Back to comp.lang.c


Contents

  global/static variables & loops Rob Janecek <robs@invalid.com> - 2012-02-14 19:56 +0000
    Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-14 12:42 -0800
    Re: global/static variables & loops Stephen Sprunk <stephen@sprunk.org> - 2012-02-14 15:01 -0600
    Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-14 20:35 -0500
      Re: global/static variables & loops Philip Lantz <prl@canterey.us> - 2012-02-14 21:18 -0800
      Re: global/static variables & loops pete <pfiland@mindspring.com> - 2012-02-15 00:53 -0500
        Re: global/static variables & loops Jonathan Leffler <jleffler@earthlink.net> - 2012-02-18 21:15 -0800
          Re: global/static variables & loops Kaz Kylheku <kaz@kylheku.com> - 2012-02-19 06:05 +0000
            Re: global/static variables & loops Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 03:15 +0200
          Re: global/static variables & loops Shao Miller <sha0.miller@gmail.com> - 2012-02-19 04:14 -0500
            Re: global/static variables & loops Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-02-19 12:32 +0000
              Re: Array 'typedef's and exclusive use of '->' versus '.' Shao Miller <sha0.miller@gmail.com> - 2012-02-19 17:00 -0500
                Re: Array 'typedef's and exclusive use of '->' versus '.' Keith Thompson <kst-u@mib.org> - 2012-02-19 16:43 -0800
                  Re: Array 'typedef's and exclusive use of '->' versus '.' Shao Miller <sha0.miller@gmail.com> - 2012-02-19 20:32 -0500
                Re: Array 'typedef's and exclusive use of '->' versus '.' Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 03:27 +0200
                  Re: Array 'typedef's and exclusive use of '->' versus '.' Shao Miller <sha0.miller@gmail.com> - 2012-02-25 02:19 -0500
                    Re: Array 'typedef's and exclusive use of '->' versus '.' Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-25 10:14 +0200
      Re: global/static variables & loops "BartC" <bc@freeuk.com> - 2012-02-15 10:47 +0000
        Re: global/static variables & loops Kaz Kylheku <kaz@kylheku.com> - 2012-02-15 11:42 +0000
          Re: global/static variables & loops "BartC" <bc@freeuk.com> - 2012-02-15 12:54 +0000
          Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 05:17 -0800
        Re: global/static variables & loops Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 03:28 +0200
      Re: global/static variables & loops August Karlstrom <fusionfile@gmail.com> - 2012-02-15 15:19 +0100
      Re: global/static variables & loops Phil Carmody <thefatphil_demunged@yahoo.co.uk> - 2012-02-22 03:12 +0200
    Re: global/static variables & loops Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-15 01:23 -0800
      Re: global/static variables & loops August Karlstrom <fusionfile@gmail.com> - 2012-02-15 14:03 +0100
        Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 05:20 -0800
          Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 08:41 -0500
            Re: global/static variables & loops Kaz Kylheku <kaz@kylheku.com> - 2012-02-16 00:20 +0000
              Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-15 21:02 -0500
                Re: global/static variables & loops "BartC" <bc@freeuk.com> - 2012-02-16 10:03 +0000
                  Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-16 07:58 -0500
                Re: global/static variables & loops Markus Wichmann <nullplan@gmx.net> - 2012-02-19 20:44 +0100
                  Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-19 15:37 -0500
                  Re: global/static variables & loops Kaz Kylheku <kaz@kylheku.com> - 2012-02-22 05:01 +0000
                    Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-22 08:12 -0500
      Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 15:55 +0100
        Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 11:05 -0500
        Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 09:13 -0800
          Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 18:25 +0100
            Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 13:25 -0500
              Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 10:51 -0800
                Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 14:45 -0500
                Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 20:47 +0100
                  Re: global/static variables & loops Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-16 04:45 -0800
                    Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-16 14:25 +0100
                      Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-16 08:10 -0800
                      Re: global/static variables & loops Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-17 00:59 -0800
              Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 20:30 +0100
                Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 15:00 -0500
                  Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 21:30 +0100
                    Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 16:00 -0500
                      Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 23:10 +0100
                        Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-15 15:50 -0800
                        Re: global/static variables & loops James Kuyper <jameskuyper@verizon.net> - 2012-02-15 19:50 -0500
                          Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-16 14:36 +0100
              Re: global/static variables & loops Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-16 03:29 -0800
        Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-15 23:37 +0100
        Re: global/static variables & loops Kaz Kylheku <kaz@kylheku.com> - 2012-02-16 00:23 +0000
          Re: global/static variables & loops Anders Wegge Keller <wegge@wegge.dk> - 2012-02-16 01:29 +0100
          Re: global/static variables & loops Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-15 21:20 -0500
        Re: global/static variables & loops Shao Miller <sha0.miller@gmail.com> - 2012-02-15 22:24 -0500
          Re: global/static variables & loops Malcolm McLean <malcolm.mclean5@btinternet.com> - 2012-02-16 01:08 -0800
        Re: global/static variables & loops Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-02-16 03:17 -0800

Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →


#17369

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 05:17 -0800
Message-ID<aed78391-6816-483b-b777-0e308ff981f0@p7g2000yqk.googlegroups.com>
In reply to#17364
On Feb 15, 11:42 am, Kaz Kylheku <k...@kylheku.com> wrote:
>
> Machine registers are globals, and they are used in tight loops.
>
Global and local are language concepts. You could certainly produce a
language in which registers are globals, and in fact some dialects of
C do that. You can refer to a register directly by name. But in most
languages registers are not available as globals.

--
Malcolm's website. Free games, programming material, and even some
poems.
http://www.malcolmmclean.site11.com/www


[toc] | [prev] | [next] | [standalone]


#17763

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-02-22 03:28 +0200
Message-ID<87ipizr70i.fsf@bazspaz.fatphil.org>
In reply to#17362
"BartC" <bc@freeuk.com> writes:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
> news:jhf24h$kmr$1@dont-email.me...
> > On 2/14/2012 2:56 PM, Rob Janecek wrote:
> 
> >> In some coding advice I saw on the internet, we are urged to "avoid
> >> referring to global or static variables inside the tightest loops".
> 
> >     That said, I'd also point out that "avoid" is not absolute;
> > perhaps "prefer not" would capture the notion more aptly.  For
> > example, it's hard to argue against the global variable in
> >
> > printf ("Hello, world!\n");
> 
> That's not likely to be part of a 'tight' loop though.

Have you ever seen the source code to busybox's ``yes'', for example?

Phil
-- 
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)

[toc] | [prev] | [next] | [standalone]


#17372

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-15 15:19 +0100
Message-ID<jhgetn$os8$1@dont-email.me>
In reply to#17348
On 2012-02-15 02:51, Stefan Ram wrote:
>    The funny thing is that it's hard to explain this in
>    beginner's classes, because there is one type of program
>    where global variables don't hurt: very small programs.

I think it is more a question of static vs. non-static global variables. 
As I see it, the only place for non-static global variables is in the 
main translation unit (although it won't hurt to make them static there 
too).


August

[toc] | [prev] | [next] | [standalone]


#17760

FromPhil Carmody <thefatphil_demunged@yahoo.co.uk>
Date2012-02-22 03:12 +0200
Message-ID<87vcmzr7rn.fsf@bazspaz.fatphil.org>
In reply to#17348
Eric Sosman <esosman@ieee-dot-org.invalid> writes:
> 	printf ("Hello, world!\n");
> 
> (If you don't see the global variable, try using fprintf() instead.)

stdout's not a global variable, it's an expression. But more than that, 
I do not see the C&V for that expression having to be a constant expression.
(perhaps my failing, enlightenment would be much appreciated).

If indeed it may be otherwise, it might not be an address constant (+/- 
constant offset).

I guess the logical conclusion from that is that this might be valid:

  FILE* __get_stdout_pointer(int i) { static FILE[3]; /* ... */ }
  ...
  extern FILE* __get_stdout_pointer(int);
  #define stdout (__get_std_file_pointer(1))

Which would be surprising, as I'm sure a lot of code has assumed that 
stdout's a constant expression.

Phil
-- 
> I'd argue that there is much evidence for the existence of a God.
Pics or it didn't happen.
-- Tom (/. uid 822)

[toc] | [prev] | [next] | [standalone]


#17361

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-02-15 01:23 -0800
Message-ID<30a23aab-a5e4-4112-8299-9c034b508ef0@t2g2000yqk.googlegroups.com>
In reply to#17326
On Feb 14, 8:46 pm, r...@zedat.fu-berlin.de (Stefan Ram) wrote:
> Rob Janecek <r...@invalid.com> writes:

> >I have no problem following the [don't access globals in inner loops
> >optimisation] advice, I'm just curious why it is true...
>
>   The advice is to only optimize,                     /when/  needed,
>   and then      to use a profiler to find the places, /where/ needed.

...but to avoid early pessimisation. That is don't write unnecessarily
poor code. Write clear straight forward code at the beginning. Then
apply Stefan's rules.

In this case it looks like a micro-optimisation to me so Stefan's
rules apply.

Oh, and why does your progranm have global variables in the first
place?

[toc] | [prev] | [next] | [standalone]


#17367

FromAugust Karlstrom <fusionfile@gmail.com>
Date2012-02-15 14:03 +0100
Message-ID<jhgaf0$fa$1@dont-email.me>
In reply to#17361
On 2012-02-15 10:23, Nick Keighley wrote:
> Oh, and why does your progranm have global variables in the first
> place?

To handle a global state maybe.


August

[toc] | [prev] | [next] | [standalone]


#17368

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 05:20 -0800
Message-ID<1819007c-1e3c-4948-abdc-662d689740c2@9g2000yqo.googlegroups.com>
In reply to#17367
On Feb 15, 1:03 pm, August Karlstrom <fusionf...@gmail.com> wrote:
> On 2012-02-15 10:23, Nick Keighley wrote:
>
> > Oh, and why does your progranm have global variables in the first
> > place?
>
> To handle a global state maybe.
>
A lot of programs work on a model / view paradigm. The model consists
of the data which the user is wanting to manipulate. The user
interface then provides various ways of seeing that data and issuing
instructions to manipulate it.

It often makes sense to have the model as a global.
--
MiniBasic - how to write a script interpreter
http://www.malcolmmclean.site11.com/www

[toc] | [prev] | [next] | [standalone]


#17371

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 08:41 -0500
Message-ID<jhgcm9$ciq$1@dont-email.me>
In reply to#17368
On 02/15/2012 08:20 AM, Malcolm McLean wrote:
> On Feb 15, 1:03�pm, August Karlstrom <fusionf...@gmail.com> wrote:
>> On 2012-02-15 10:23, Nick Keighley wrote:
>>
>>> Oh, and why does your progranm have global variables in the first
>>> place?
>>
>> To handle a global state maybe.
>>
> A lot of programs work on a model / view paradigm. The model consists
> of the data which the user is wanting to manipulate. The user
> interface then provides various ways of seeing that data and issuing
> instructions to manipulate it.
> 
> It often makes sense to have the model as a global.

Only if it never makes sense to have more than one instance of the model
manipulated by the same program. I've often written programs which only
manipulated a single model; but most, if not all, of those models were
things that there could have been two or more of in a single program.
When that's the case, it makes more sense to pass the model around
though pointer arguments.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#17406

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-16 00:20 +0000
Message-ID<20120215161957.631@kylheku.com>
In reply to#17371
On 2012-02-15, James Kuyper <jameskuyper@verizon.net> wrote:
> On 02/15/2012 08:20 AM, Malcolm McLean wrote:
>> On Feb 15, 1:03�pm, August Karlstrom <fusionf...@gmail.com> wrote:
>>> On 2012-02-15 10:23, Nick Keighley wrote:
>>>
>>>> Oh, and why does your progranm have global variables in the first
>>>> place?
>>>
>>> To handle a global state maybe.
>>>
>> A lot of programs work on a model / view paradigm. The model consists
>> of the data which the user is wanting to manipulate. The user
>> interface then provides various ways of seeing that data and issuing
>> instructions to manipulate it.
>> 
>> It often makes sense to have the model as a global.
>
> Only if it never makes sense to have more than one instance of the model
> manipulated by the same program. 

Suppose it makes sense to have three instances of the model.

Where will you keep those three instances? 

[toc] | [prev] | [next] | [standalone]


#17414

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-15 21:02 -0500
Message-ID<jhho49$ces$1@dont-email.me>
In reply to#17406
On 2/15/2012 7:20 PM, Kaz Kylheku wrote:
> On 2012-02-15, James Kuyper<jameskuyper@verizon.net>  wrote:
>> On 02/15/2012 08:20 AM, Malcolm McLean wrote:
>>> On Feb 15, 1:03�pm, August Karlstrom<fusionf...@gmail.com>  wrote:
>>>> On 2012-02-15 10:23, Nick Keighley wrote:
>>>>
>>>>> Oh, and why does your progranm have global variables in the first
>>>>> place?
>>>>
>>>> To handle a global state maybe.
>>>>
>>> A lot of programs work on a model / view paradigm. The model consists
>>> of the data which the user is wanting to manipulate. The user
>>> interface then provides various ways of seeing that data and issuing
>>> instructions to manipulate it.
>>>
>>> It often makes sense to have the model as a global.
>>
>> Only if it never makes sense to have more than one instance of the model
>> manipulated by the same program.
>
> Suppose it makes sense to have three instances of the model.
>
> Where will you keep those three instances?

     C'mon, Kaz, you know better.  Usually, an instance inhabits a
`static' somewhere (so its name is not available outside the scope
of its keeper), or it inhabits dynamically allocated memory (which
has no name at all).

     True story: A former employer's flagship product did things with
documents, and the earliest versions could handle only one document
at a time.  THE document was, fairly naturally, described by a host
of global variables: What are THE page margins, what is THE set of
paragraph styles, what is THE associated file name, and so on.  At
some point (before I joined), the product was extended to handle
multiple documents simultaneously -- but by then, all those globals
had infiltrated themselves into too many places to extricate; there
just Was Not Going To Be an attempt to track down every reference to
every global and route it through a pointer instead, nor to inflate
all the functions and function calls to pass the pointer around.

     Solution?  The overarching framework noticed when the user moved
from Document A to Document B, and swapped things around to make it
work.  It saved all the globals for A into one big struct, and then
restored all their values from B's struct (build-time tools created
the struct definition and the save/restore code, with a little help
from source-code markers to identify the globals).  When the user then
moved to Document C, B's globals were squirrelled away and C's values
overwrote them.

     By the time I left that employer, the size of the automatically-
generated struct and of the save/restore functions had grown to the
point where some platforms' compilers could no longer handle them,
and the tools had been modified to break the struct into three, with
three sets of functions.  Also, just moving your mouse from Window A
to Window B could drive your paging disk berserk as it tried to handle
all these references to globals scattered hither and yon all over the
address space; you could force your workstation to its knees just by
flicking your mouse back and forth on the screen.

     That's the power of globals.

     I take two lessons from this experience: First, sufficient ingenuity
and a willingness to hack can come up with a short-term solution to most
any problem.  Second, short-term solutions have little staying power.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#17426

From"BartC" <bc@freeuk.com>
Date2012-02-16 10:03 +0000
Message-ID<jhikae$qbq$1@dont-email.me>
In reply to#17414
"Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
news:jhho49$ces$1@dont-email.me...
> On 2/15/2012 7:20 PM, Kaz Kylheku wrote:

>> Where will you keep those three instances?

>     True story: A former employer's flagship product did things with
> documents, and the earliest versions could handle only one document
> at a time.  THE document was, fairly naturally, described by a host
> of global variables:
...
>     By the time I left that employer, the size of the automatically-
> generated struct and of the save/restore functions had grown to the
> point where some platforms' compilers could no longer handle them,
> and the tools had been modified to break the struct into three, with
> three sets of functions.  Also, just moving your mouse from Window A
> to Window B could drive your paging disk berserk as it tried to handle
> all these references to globals scattered hither and yon all over the
> address space; you could force your workstation to its knees just by
> flicking your mouse back and forth on the screen.
>
>     That's the power of globals.

Wasn't it possible just to run multiple instances of the program?

Anyway I can't quite believe the situation was that bad; even copying a
million variables (today) or perhaps a thousand (years ago), would hardly
have that impact.

>     I take two lessons from this experience: First, sufficient ingenuity
> and a willingness to hack can come up with a short-term solution to most
> any problem.  Second, short-term solutions have little staying power.

I think I prefer the solution you describe (call SelectDocument(n), and
continue to be able to use all these settings in a simple manner) than have
to acknowledge the 'multi-documenticity' of the application in a million
places in the source code. (And when there's a further enhancement, applying
multiplicity to something you hadn't thought of before, have to do it all
again.)

-- 
Bartc 

[toc] | [prev] | [next] | [standalone]


#17442

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-16 07:58 -0500
Message-ID<jhiuho$clb$1@dont-email.me>
In reply to#17426
On 2/16/2012 5:03 AM, BartC wrote:
> "Eric Sosman" <esosman@ieee-dot-org.invalid> wrote in message
> news:jhho49$ces$1@dont-email.me...
>> On 2/15/2012 7:20 PM, Kaz Kylheku wrote:
>
>>> Where will you keep those three instances?
>
>> True story: A former employer's flagship product did things with
>> documents, and the earliest versions could handle only one document
>> at a time. THE document was, fairly naturally, described by a host
>> of global variables:
> ...
>> By the time I left that employer, the size of the automatically-
>> generated struct and of the save/restore functions had grown to the
>> point where some platforms' compilers could no longer handle them,
>> and the tools had been modified to break the struct into three, with
>> three sets of functions. Also, just moving your mouse from Window A
>> to Window B could drive your paging disk berserk as it tried to handle
>> all these references to globals scattered hither and yon all over the
>> address space; you could force your workstation to its knees just by
>> flicking your mouse back and forth on the screen.
>>
>> That's the power of globals.
>
> Wasn't it possible just to run multiple instances of the program?

     The whole point was to avoid running multiple copies.  That
way, you could (for example) grab a whole bunch of documents at
once and change their page sizes from Letter to A4 in a single
operation, instead of making the same change in N invocations of
the same program.

> Anyway I can't quite believe the situation was that bad; even copying a
> million variables (today) or perhaps a thousand (years ago), would hardly
> have that impact.

     I was there, you were not.  I saw the page disk thrashing, you
did not.  I saw the system freeze for as much as four seconds when
the mouse went from one window to another (although I admit most
freezes were less than three seconds).

     But, hey: Who am I to challenge your unbelief?

>> I take two lessons from this experience: First, sufficient ingenuity
>> and a willingness to hack can come up with a short-term solution to most
>> any problem. Second, short-term solutions have little staying power.
>
> I think I prefer the solution you describe (call SelectDocument(n), and
> continue to be able to use all these settings in a simple manner) than have
> to acknowledge the 'multi-documenticity' of the application in a million
> places in the source code. (And when there's a further enhancement,
> applying
> multiplicity to something you hadn't thought of before, have to do it all
> again.)

     Been there, done that, found it bad.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#17618

FromMarkus Wichmann <nullplan@gmx.net>
Date2012-02-19 20:44 +0100
Message-ID<620819-gu6.ln1@voyager.wichi.de.vu>
In reply to#17414
On 16.02.2012 03:02, Eric Sosman wrote:
>      C'mon, Kaz, you know better.  Usually, an instance inhabits a
> `static' somewhere (so its name is not available outside the scope
> of its keeper), or it inhabits dynamically allocated memory (which
> has no name at all).
> 
>      True story: A former employer's flagship product did things with
> documents, and the earliest versions could handle only one document
> at a time.  THE document was, fairly naturally, described by a host
> of global variables: What are THE page margins, what is THE set of
> paragraph styles, what is THE associated file name, and so on.  At
> some point (before I joined), the product was extended to handle
> multiple documents simultaneously -- but by then, all those globals
> had infiltrated themselves into too many places to extricate; there
> just Was Not Going To Be an attempt to track down every reference to
> every global and route it through a pointer instead, nor to inflate
> all the functions and function calls to pass the pointer around.
> 

Where's the problem? Write a tool that notices when a function uses one
of the globals (you surely had at least a list of them, hadn't you?).
Then rewrite the function prototype in the header, if any, and the
function declaration in the code file so that it takes a pointer to a
struct as first argument and references the globals through that
pointer. Then remove any _definition_ of the globals and bundle them in
said struct. For starters, define one static instance of the struct
somewhere, but remove it later after inclusion of multiple-instance code.

By now, every old usage of the functions should result in a compiler
error or warning, and every usage of the globals should result in a
linker error. Correct those and you are nearly done. Now you only need
to find leftover locally defined static-duration variables that only
work for one document and eradicate those. Done!

>      Solution?  The overarching framework noticed when the user moved
> from Document A to Document B, and swapped things around to make it
> work.  It saved all the globals for A into one big struct, and then
> restored all their values from B's struct (build-time tools created
> the struct definition and the save/restore code, with a little help
> from source-code markers to identify the globals).  When the user then
> moved to Document C, B's globals were squirrelled away and C's values
> overwrote them.
> 

So you had to create the struct anyway already!

>      By the time I left that employer, the size of the automatically-
> generated struct and of the save/restore functions had grown to the
> point where some platforms' compilers could no longer handle them,

How is that possible? You would need to break some hard limit in the
compiler, like 64KB on a 16-bit machine. You had 64KB worth of globals?

> and the tools had been modified to break the struct into three, with
> three sets of functions.  Also, just moving your mouse from Window A
> to Window B could drive your paging disk berserk as it tried to handle
> all these references to globals scattered hither and yon all over the
> address space; you could force your workstation to its knees just by
> flicking your mouse back and forth on the screen.
> 

At that point the "solution" has become unviable and another solution
must be sought. But, well, that's gonna cost money, right?

One solution would have been to leave the program in its state with all
the globals and just put a wrapper there to handle multiple documents
with multiple processes. Then the OS can worry about the swap drive,
with copy-on-write pages and such.

>      That's the power of globals.
> 
>      I take two lessons from this experience: First, sufficient ingenuity
> and a willingness to hack can come up with a short-term solution to most
> any problem.  Second, short-term solutions have little staying power.
> 

Good design helps, too: If the company had worked object-orientedly from
the start (which would have resulted in a program that used those
structs from the start), much money could have been saved. But of
course, there would have been more money needed to be spent before the
first release.

What do we learn? Global variables are usually a hack that can be
removed by good design and a good compiler. Seriously, a compiler with
link time optimization should not yield worse results with a structured
global than with individual globals.

Ciao,
Markus

[toc] | [prev] | [next] | [standalone]


#17624

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-19 15:37 -0500
Message-ID<jhrmi0$7o4$1@dont-email.me>
In reply to#17618
On 2/19/2012 2:44 PM, Markus Wichmann wrote:
> On 16.02.2012 03:02, Eric Sosman wrote:
>>
>>       True story: A former employer's flagship product did things with
>> documents, and the earliest versions could handle only one document
>> at a time.  THE document was, fairly naturally, described by a host
>> of global variables: What are THE page margins, what is THE set of
>> paragraph styles, what is THE associated file name, and so on.  At
>> some point (before I joined), the product was extended to handle
>> multiple documents simultaneously -- but by then, all those globals
>> had infiltrated themselves into too many places to extricate; there
>> just Was Not Going To Be an attempt to track down every reference to
>> every global and route it through a pointer instead, nor to inflate
>> all the functions and function calls to pass the pointer around.
>
> Where's the problem?

     Scale.  It is easy to kill one rhinovirus, but rather more
difficult to cure the common cold.

> Write a tool that notices when a function uses one
> of the globals (you surely had at least a list of them, hadn't you?).

     Yes, implicitly by markers around their definitions.  The build
tools used the markers to generate the "backing store" structs and
the save/restore functions that handled them, and it would have been
easy to make them emit the information in other forms, as well.

> Then rewrite the function prototype in the header, if any, and the
> function declaration in the code file so that it takes a pointer to a
> struct as first argument and references the globals through that
> pointer.  [...]

     You've put "if any" in the wrong place: Headers yes, prototypes
no, because the code's origins antedated the ANSI Standard by about
a decade.  (In later years I supported a move to "ANSIfy" the code
base, but engineers with greater clout and seniority argued against
it and the project never got started.)

> By now, every old usage of the functions should result in a compiler
> error or warning, and every usage of the globals should result in a
> linker error. Correct those and you are nearly done.

     Kill a billion rhinovirii and you're well on your way to being
rid of your cold.

> Now you only need
> to find leftover locally defined static-duration variables that only
> work for one document and eradicate those.

     Obviously any such leftovers had already been eliminated, or the
swap-and-restore hack would not have worked.

>>       By the time I left that employer, the size of the automatically-
>> generated struct and of the save/restore functions had grown to the
>> point where some platforms' compilers could no longer handle them,
>
> How is that possible?

     Scale.  (Is there an echo in here?)

> You would need to break some hard limit in the
> compiler, like 64KB on a 16-bit machine. You had 64KB worth of globals?

     Easily.  How many did we eventually have?  Sorry, I don't recall;
it was more than a quarter-century ago.  I can't even recall whether
the limits we hit pertained to struct size or to function size, nor
which platforms' compilers croaked on them.  (All were 32-bit, by the
way.  A serious effort to get our stuff running on a 16-bit compiler
with a 32-bit address extension proved fruitless, and our only 64-bit
port came along rather late in the code base's life.)

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#17769

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-22 05:01 +0000
Message-ID<20120221210039.481@kylheku.com>
In reply to#17618
On 2012-02-19, Markus Wichmann <nullplan@gmx.net> wrote:
> On 16.02.2012 03:02, Eric Sosman wrote:
>>      C'mon, Kaz, you know better.  Usually, an instance inhabits a
>> `static' somewhere (so its name is not available outside the scope
>> of its keeper), or it inhabits dynamically allocated memory (which
>> has no name at all).
>> 
>>      True story: A former employer's flagship product did things with
>> documents, and the earliest versions could handle only one document
>> at a time.  THE document was, fairly naturally, described by a host
>> of global variables: What are THE page margins, what is THE set of
>> paragraph styles, what is THE associated file name, and so on.  At
>> some point (before I joined), the product was extended to handle
>> multiple documents simultaneously -- but by then, all those globals
>> had infiltrated themselves into too many places to extricate; there
>> just Was Not Going To Be an attempt to track down every reference to
>> every global and route it through a pointer instead, nor to inflate
>> all the functions and function calls to pass the pointer around.
>> 
>
> Where's the problem? Write a tool that notices when a function uses one

Undoubtedly there were subtleties, otherwise Eric would have probably
made an afternoon of doing exactly this.

[toc] | [prev] | [next] | [standalone]


#17783

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-22 08:12 -0500
Message-ID<ji2pk8$r2f$1@dont-email.me>
In reply to#17769
On 2/22/2012 12:01 AM, Kaz Kylheku wrote:
> On 2012-02-19, Markus Wichmann<nullplan@gmx.net>  wrote:
>> On 16.02.2012 03:02, Eric Sosman wrote:
>>>       C'mon, Kaz, you know better.  Usually, an instance inhabits a
>>> `static' somewhere (so its name is not available outside the scope
>>> of its keeper), or it inhabits dynamically allocated memory (which
>>> has no name at all).
>>>
>>>       True story: A former employer's flagship product did things with
>>> documents, and the earliest versions could handle only one document
>>> at a time.  THE document was, fairly naturally, described by a host
>>> of global variables: What are THE page margins, what is THE set of
>>> paragraph styles, what is THE associated file name, and so on.  At
>>> some point (before I joined), the product was extended to handle
>>> multiple documents simultaneously -- but by then, all those globals
>>> had infiltrated themselves into too many places to extricate; there
>>> just Was Not Going To Be an attempt to track down every reference to
>>> every global and route it through a pointer instead, nor to inflate
>>> all the functions and function calls to pass the pointer around.
>>>
>>
>> Where's the problem? Write a tool that notices when a function uses one
>
> Undoubtedly there were subtleties, otherwise Eric would have probably
> made an afternoon of doing exactly this.

     Nothing really subtle: Just three million lines of code, still
under active development by 80+ programmers.  "Three million" is not
a large program (program suite, really) by today's standards, but
the tooling available to us a quarter-century ago strained to handle
that much code.  A full build took five-ish hours on our fastest
platform, eight or nine on our slowest.  None of our machines had
enough horsepower to run a built-entirely-for-debug version; you had
to decide which modules you wanted debuggable, build those with
debug flags, and link with non-debug objects for the rest.  And so
on: Nothing subtle, just uncomfortably large.

     There was also what might be called "product inertia."  A hack
had been invented, and had worked well enough in the beginning.  It
was no longer working as well as it had when the young product was
only (maybe) three quarters of a million lines, but at least it let
the program operate, albeit with speed bumps.  Faced with the choice
of expending development effort on (1) snazzy new features to improve
the product's competitive position, or (2) internal cleanup that would
lead to an improvement we'd not be able to "sell" while inevitably
producing its own crop of new bugs -- well, guess which projects the
management decided to fund.

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#17373

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 15:55 +0100
Message-ID<87k43o9mdn.fsf@huddi.jernurt.dk>
In reply to#17361
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:

> Oh, and why does your progranm have global variables in the first
> place?

 Can you give an example of a non-trivial program, that has no global
state in any way?

-- 
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

[toc] | [prev] | [next] | [standalone]


#17374

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 11:05 -0500
Message-ID<jhgl3c$ubm$1@dont-email.me>
In reply to#17373
On 02/15/2012 09:55 AM, Anders Wegge Keller wrote:
> Nick Keighley <nick_keighley_nospam@hotmail.com> writes:
> 
>> Oh, and why does your progranm have global variables in the first
>> place?
> 
>  Can you give an example of a non-trivial program, that has no global
> state in any way?

Most of the programs I'm responsible for were originally written by
other people, and they usually made a lot of use of global variables at
the time I became responsible for them. However, I've slowly been
removing those variables, and the only difficulty with doing so that
I've ever had was finding adequate justification for bothering to spend
the time needed to remove them.

The code I wrote entirely myself almost never uses globals, but I don't
know whether it would count as non-trivial for your purposes. However,
almost all of my code has to be linked to various libraries written by
other people, and those libraries often use globals, such as errno in
<errno.h>. errno isn't required to be a global, but it often is, so I
guess you're right - it all has some global state, even if there's no
real reason why global state is needed.
-- 
James Kuyper

[toc] | [prev] | [next] | [standalone]


#17375

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 09:13 -0800
Message-ID<cd40f70d-efef-479d-b6fe-b468140a7763@t2g2000yqk.googlegroups.com>
In reply to#17373
On Feb 15, 2:55 pm, Anders Wegge Keller <we...@wegge.dk> wrote:
> Nick Keighley <nick_keighley_nos...@hotmail.com> writes:
> > Oh, and why does your progranm have global variables in the first
> > place?
>
>  Can you give an example of a non-trivial program, that has no global
> state in any way?
>
Ultimately you need some way of doing IO, which means communicating
with some physical device, which is likely to mean memory mapping at a
low level and thus global control variables at a high level.

But if we can assume that fopen() and printf() work by magic, then
it's possible to write the program without any global state. Trivally,
you could declare a struct myglobals and pass it to every function in
the call tree. But often you don't need to do this, the program it's
just natural to declare the few persistent state varibales as local to
main and pass them as parameters.

The program I'm currently working on has no globals or statics, for
example. It takes quite a rich set of command line arguments friom the
user, ands so it calls a general purpose "options parser" which stores
the command line in a temporary structure, and allows queries. Then it
destroys that structure after extracting about a dozen parameter
variables. It then loads a csv file into a CSV structure, extracts two
columns of data as specified by the user, and destoys the CSV
structure. The columns are converted to a data density map, using a
palette specified byt eh user, and then written out as a JPEG.

So no globals required. It does have state in main which persists for
the life of the program, however.
--
Coming soon: the data density program
http://www.malcolmmclean.site11.com/www

[toc] | [prev] | [next] | [standalone]


#17376

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 18:25 +0100
Message-ID<87d39g9fgm.fsf@huddi.jernurt.dk>
In reply to#17375
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> But if we can assume that fopen() and printf() work by magic, then
> it's possible to write the program without any global state. Trivally,
> you could declare a struct myglobals and pass it to every function in
> the call tree.

 That is global state in my book. 

> But often you don't need to do this, the program it's just natural
> to declare the few persistent state varibales as local to main and
> pass them as parameters.

 As is this, if you need to propagate the same value unchanged down
the call tree from main().

 My point is that no matter how you try to hide it, whether it's to
get rid of global variables, just because they are baaad, or if you
actually need to do something in a smarter way, there is hardly a
program that hasn't got a global state. And in that case, I fail to
see why the program would be any worse, by actually admitting the
fact.

-- 
/Wegge

Leder efter redundant peering af dk.*,linux.debian.*

[toc] | [prev] | [next] | [standalone]


Page 2 of 4 — ← Prev page 1 [2] 3 4  Next page →

Back to top | Article view | comp.lang.c


csiph-web