Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #17326 > unrolled thread
| Started by | Rob Janecek <robs@invalid.com> |
|---|---|
| First post | 2012-02-14 19:56 +0000 |
| Last post | 2012-02-16 03:17 -0800 |
| Articles | 20 on this page of 64 — 18 participants |
Back to article view | Back to comp.lang.c
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 →
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Phil Carmody <thefatphil_demunged@yahoo.co.uk> |
|---|---|
| Date | 2012-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]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | August Karlstrom <fusionfile@gmail.com> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-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]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-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]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-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]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-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]
| From | Markus Wichmann <nullplan@gmx.net> |
|---|---|
| Date | 2012-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]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-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]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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