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 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#17378

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 13:25 -0500
Message-ID<jhgt9t$hkn$1@dont-email.me>
In reply to#17376
On 02/15/2012 12:25 PM, Anders Wegge Keller wrote:
> 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.

If that counts as global state, then storing global state in global
variables is clearly not necessary.

...
>  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, ...

Your use of "just" and "baaad" implies that you think that the idea that
globals are bad is an unjustified prejudice, rather than the
well-justified judgment that it actually is. Are you actually unaware of
the problems that they can cause?

> ... 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.
n
The key problem with global variables is visibility; by being visible
everywhere, they can be affected by anything, which can make it
difficult to determine what part of the program caused those variables
to have their current value, or what part had it's behavior affected by
the value. Variables which are local to main() and are passed by a
pointer to subroutines need not be passed to all subroutines, but only
the ones that actually need to have access to those variables, and that
could be a different set of subroutines for different variables. Making
information available to a subroutine only on a "need to know" basis is
good software design. It can be overdone, but that's seldom a real-world
problem.
-- 
James Kuyper

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


#17379

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 10:51 -0800
Message-ID<036aeabb-2659-4ad7-b950-ed4f649d2645@w4g2000vbc.googlegroups.com>
In reply to#17378
On Feb 15, 6:25 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 02/15/2012 12:25 PM, Anders Wegge Keller wrote:
>
> > Malcolm McLean <malcolm.mcle...@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.
>
> If that counts as global state, then storing global state in global
> variables is clearly not necessary.
>
If you take a program, list every global variable, pack them into a
structure, and then pass a pointer to the structure to every function
in the call tree, you aren't really achieving much. However you are
making it easier for the program to accept two states (think a GUI
program going from a single document model to a tabbed interface
allowing multiple documents.
>
> The key problem with global variables is visibility; by being visible
> everywhere,
>
The other problem is portability and testing.

Lets say we do this

EMPLOYEE myemployees[100];
int Nemployees;
double averagesalary()
{
  /* step through the employee array calculating average salary */
}

Now it's hard to test. We have to set up the employees structure to
check it.

Let's say we do this instead

double average(void *data, int offset, int stride, int N)

it takes a bit more writing. But once we've done, we can copy and
paste and use the code in many different applications, which might not
have anything else in common with each other. And we're much more
likely to document what happens when N == 0, which is where the bug is
likely to creep in, or what happens when we get Mr Fred the Shred and
salary goes to DBL_MAX (apologies to American readers who won't
understand this reference).

--
Visit my website. Data density program coming soon
http://www.malcommclean.site11.com/www

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


#17385

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 14:45 -0500
Message-ID<jhh21g$f1j$1@dont-email.me>
In reply to#17379
On 02/15/2012 01:51 PM, Malcolm McLean wrote:
...
> If you take a program, list every global variable, pack them into a
> structure, and then pass a pointer to the structure to every function
> in the call tree, you aren't really achieving much.

Yes, that's right. I wouldn't pass the whole set of variables in main()
to each subroutine of main(), but only the parts needed by that subroutine.
-- 
James Kuyper

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


#17386

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 20:47 +0100
Message-ID<874nuranf8.fsf@huddi.jernurt.dk>
In reply to#17379
Malcolm McLean <malcolm.mclean5@btinternet.com> writes:

> Lets say we do this
> 
> EMPLOYEE myemployees[100];
> int Nemployees;
> double averagesalary()
> {
>   /* step through the employee array calculating average salary */
> }

 I don't know if I've made myself clear previously, but I'm in this
thread, asking about programs having *NO GLOBAL STATE AT ALL*.

 No debug levels.
 No log destinations.
 No file handles.
 No nothing.

 I have no trouble seing why *DATA* should not be globally visible,
unless there are some very good reasons for them being so, like my
co-existing embedded threads, mentioned elsewhere. But that is beyond
the express negative I questioned earlier.

-- 
/Wegge

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

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


#17440

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-02-16 04:45 -0800
Message-ID<d4a54b94-e2ea-415f-8f93-6cbf76e08e65@i18g2000yqf.googlegroups.com>
In reply to#17386
On Feb 15, 7:47 pm, Anders Wegge Keller <we...@wegge.dk> wrote:
> Malcolm McLean <malcolm.mcle...@btinternet.com> writes:

>  I don't know if I've made myself clear previously, but I'm in this
> thread, asking about programs having *NO GLOBAL STATE AT ALL*.

I think you're trying to extend your "global state" beyond what is
reasonable. Unless we're writing in some sort of functional
programming language the we're going to have GS, and even with an FP I
suspect you'd claim GS was present.

I'm talking about global variables. Data that's accessible throughout
the program. Stuff that's hard to debug because *anyone* could have
fiddled with it.

I accept taht most real world programs have *some* global data, but I
submit it should be kept to a minimum.

>  No debug levels.

honourable exception.

Though large programs with global debug state tend to drown in
diagnostics. It needs to eb much more fine grained to be useful.
Turning on TRACE2(the noisiest level) globally on one system simply
brought it to its knees.

>  No log destinations.

honourable exception.

It's handy to have more than one log though

>  No file handles.

I don't accept that these are "global" in my sense. Except for stdin,
stout and stderr. And the large systems I've worked on didn't really
use 'em.

>  No nothing.

oh you can have as many global nothings as you like! :-)

>  I have no trouble seing why *DATA* should not be globally visible,
> unless there are some very good reasons for them being so,

we're in violent agreement then.

> like my
> co-existing embedded threads, mentioned elsewhere. But that is beyond
> the express negative I questioned earlier.

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


#17443

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-16 14:25 +0100
Message-ID<8762f69ah5.fsf@huddi.jernurt.dk>
In reply to#17440
Nick Keighley <nick_keighley_nospam@hotmail.com> writes:

> On Feb 15, 7:47 pm, Anders Wegge Keller <we...@wegge.dk> wrote:
> > Malcolm McLean <malcolm.mcle...@btinternet.com> writes:
> 
> >  I don't know if I've made myself clear previously, but I'm in this
> > thread, asking about programs having *NO GLOBAL STATE AT ALL*.
> 
> I think you're trying to extend your "global state" beyond what is
> reasonable. Unless we're writing in some sort of functional
> programming language the we're going to have GS, and even with an FP I
> suspect you'd claim GS was present.
> 
> I'm talking about global variables. Data that's accessible throughout
> the program. Stuff that's hard to debug because *anyone* could have
> fiddled with it.

 I was asking (and extending global state), to point out why strict
adherence to "no glabals" without thought isn't clever.


-- 
/Wegge

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

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


#17448

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-16 08:10 -0800
Message-ID<04d23f01-ef5e-427c-9f32-83c2e7206c18@d15g2000yqg.googlegroups.com>
In reply to#17443
On Feb 16, 1:25 pm, Anders Wegge Keller <we...@wegge.dk> wrote:
>
>  I was asking (and extending global state), to point out why strict
> adherence to "no glabals" without thought isn't clever.
>
Let's say we do this


double ehks(double x, bool write)
{
  static double X;

  if(write)
    X = x;
  return X;
}

we've avoided making X global, but we haven't achived much. However
we've done something psychologically, the function ehks() is much more
likely to be documented than just X. And we can intercept reads or
writes to X.
--
MiniBasic - how to write a script interpreter
http://www.malcolmmclean.site11.com/www

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


#17504

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-02-17 00:59 -0800
Message-ID<9faa3bca-a4ed-4894-bc93-f8c8727dfae6@18g2000yqe.googlegroups.com>
In reply to#17443
On Feb 16, 1:25 pm, Anders Wegge Keller <we...@wegge.dk> wrote:

>  I was asking (and extending global state), to point out why strict
> adherence to "no glabals" without thought isn't clever.

lots of things in programming done without thought are bad.

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


#17382

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 20:30 +0100
Message-ID<878vk3ao7m.fsf@huddi.jernurt.dk>
In reply to#17378
James Kuyper <jameskuyper@verizon.net> writes:

> On 02/15/2012 12:25 PM, Anders Wegge Keller wrote:

>>  That is global state in my book.
 
> If that counts as global state, then storing global state in global
> variables is clearly not necessary.

 No, but when the effect is the same anyway, why add another level of
complexity?
 
>>  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, ...
 
> Your use of "just" and "baaad" implies that you think that the idea
> that globals are bad is an unjustified prejudice,

 It very often is an unreflected, almost religious observance. Just
like "gotos are bad". The next thing you see, is people mechanically
replacing a global variable with a static, and adding getters and
setters because the same state is still needed globally. 

> rather than the well-justified judgment that it actually is.

 If it quacks like a duck, walks like a duck and swims like a duck, it
probably is a duck, no matter how you dress it up. 

> Are you actually unaware of the problems that they can cause?

 If people write bad code, they will get into trouble, no matter what
paradigm they adhere to. I can think of lots of ways a program can
become difficult to manage by doing something stupid with a
global. But that is not exclusive to that style.

>> ... 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.

> The key problem with global variables is visibility; by being
> visible everywhere, they can be affected by anything, which can make
> it difficult to determine what part of the program caused those
> variables to have their current value, or what part had it's
> behavior affected by the value.

 Scratch the getter/setter pattern, and the global struct pointer
that's passed down the call tree then. *OR* prototype the darn things
as const outside the translation unit that actually has to modify
them, and see where the compiler complains. (And remember to remove
the const prototype afterwards, unless you want to see some
spectacular failures :)

> Variables which are local to main() and are passed by a
> pointer to subroutines need not be passed to all subroutines, but only
> the ones that actually need to have access to those variables, and that
> could be a different set of subroutines for different variables. 

 Unless you have a very limited state space, that will lead to some
very convoluted and error-prone code. 

> Making information available to a subroutine only on a "need to
> know" basis is good software design. It can be overdone, but that's
> seldom a real-world problem.

 You should try to do real-time machine control with 10-15
co-concurrent tasks running on a 80186 platform, where each individual
thread has a stack in the range 128 to 256 bytes, and avoid overdoing
need-to-know :) I'm in the 0.1%, where overdoing things are a
real-world problem.

-- 
/Wegge

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

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


#17387

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 15:00 -0500
Message-ID<jhh2sd$kt1$1@dont-email.me>
In reply to#17382
On 02/15/2012 02:30 PM, Anders Wegge Keller wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 02/15/2012 12:25 PM, Anders Wegge Keller wrote:
> 
>>>  That is global state in my book.
>  
>> If that counts as global state, then storing global state in global
>> variables is clearly not necessary.
> 
>  No, but when the effect is the same anyway, why add another level of
> complexity?

Because the effect is not the same - the visibility is quite different.

...
>> rather than the well-justified judgment that it actually is.
> 
>  If it quacks like a duck, walks like a duck and swims like a duck, it
> probably is a duck, no matter how you dress it up. 

Well, that works both ways - labeling it a prejudice doesn't make it
cease to be a well-justified judgment.

>> The key problem with global variables is visibility; by being
>> visible everywhere, they can be affected by anything, which can make
>> it difficult to determine what part of the program caused those
>> variables to have their current value, or what part had it's
>> behavior affected by the value.
> 
>  Scratch the getter/setter pattern, and the global struct pointer
> that's passed down the call tree then. *OR* prototype the darn things
> as const outside the translation unit that actually has to modify
> them, and see where the compiler complains. (And remember to remove
> the const prototype afterwards, unless you want to see some
> spectacular failures :)

I'm not sure what any of that word salad has to do with what I was
talking about. Can you re-write it to make the relevance clearer?

>> Variables which are local to main() and are passed by a
>> pointer to subroutines need not be passed to all subroutines, but only
>> the ones that actually need to have access to those variables, and that
>> could be a different set of subroutines for different variables. 
> 
>  Unless you have a very limited state space, that will lead to some
> very convoluted and error-prone code. 

Not in my experience.

>> Making information available to a subroutine only on a "need to
>> know" basis is good software design. It can be overdone, but that's
>> seldom a real-world problem.
> 
>  You should try to do real-time machine control with 10-15
> co-concurrent tasks running on a 80186 platform, where each individual
> thread has a stack in the range 128 to 256 bytes, and avoid overdoing
> need-to-know :) I'm in the 0.1%, where overdoing things are a
> real-world problem.

Limited stack space is something I've little recent experience with, but
I agree that it's an excellent reason to avoid using the stack; in
extreme cases, even passing pointers on the stack becomes problematic -
but you should rarely need to go all the way to global visibility to
avoid that problem. You have a greater need to use objects with static
storage duration than I do, but you don't have to make every single one
of them globally visible. I've a number of such objects in my own code.
Most of them have block scope, a few have file scope - but none has
external linkage.
-- 
James Kuyper

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


#17395

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 21:30 +0100
Message-ID<87y5s396wj.fsf@huddi.jernurt.dk>
In reply to#17387
James Kuyper <jameskuyper@verizon.net> writes:

> On 02/15/2012 02:30 PM, Anders Wegge Keller wrote:

>>  If it quacks like a duck, walks like a duck and swims like a duck, it
>> probably is a duck, no matter how you dress it up. 
> 
> Well, that works both ways - labeling it a prejudice doesn't make it
> cease to be a well-justified judgment.

 Yoy have missed the point. I'm talking about cases like

 int debug_level;

 versus:

 static int debug_level
 int get_debug_level(void) { return debug_level; }
 void set_debug_level(int lvl) { debug_level = lvl; }

 I'm not trying to justify "All data should be global", as you seem to
imply. I'm questioning "No data should be global". There is a world
between those two statements.
 
>>  Scratch the getter/setter pattern, and the global struct pointer
>> that's passed down the call tree then. *OR* prototype the darn things
>> as const outside the translation unit that actually has to modify
>> them, and see where the compiler complains. (And remember to remove
>> the const prototype afterwards, unless you want to see some
>> spectacular failures :)
 
> I'm not sure what any of that word salad has to do with what I was
> talking about. Can you re-write it to make the relevance clearer?

 If my explanation above doesn't make it clearer, please ask
again. But I think we have two very different opinions about what
"state" actually means at present.

>>  Unless you have a very limited state space, that will lead to some
>> very convoluted and error-prone code. 
 
> Not in my experience.

 Try implementing GNU ls without globals. I know that the whole lot
are statics, since the code is in just one TU, but imagine something
of a similar magnitude then. The first few levels of functions will
have prototypes of several pages.

>>  You should try to do real-time machine control with 10-15
>> co-concurrent tasks running on a 80186 platform, where each
>> individual thread has a stack in the range 128 to 256 bytes, and
>> avoid overdoing need-to-know :) I'm in the 0.1%, where overdoing
>> things are a real-world problem.
 
> Limited stack space is something I've little recent experience with,
> but I agree that it's an excellent reason to avoid using the stack;
> in extreme cases, even passing pointers on the stack becomes
> problematic - but you should rarely need to go all the way to global
> visibility to avoid that problem. You have a greater need to use
> objects with static storage duration than I do, but you don't have
> to make every single one of them globally visible. I've a number of
> such objects in my own code.  Most of them have block scope, a few
> have file scope - but none has external linkage.

 When data is shared between several threads, and each thread live in
its own translation unit, that cannot be helped. The central part is
an array-esque (80186 memory model limitations) representation of
system state. Most manipulation happens through a set of state-event
machines, each doing their part. 

 And mind, this is hardware that was state of the art in the late
1980's, and we have been stuck on that ever since, because it works
too good to warrant a major architecture rewrite.

-- 
/Wegge

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

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


#17398

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 16:00 -0500
Message-ID<jhh6d5$aps$1@dont-email.me>
In reply to#17395
On 02/15/2012 03:30 PM, Anders Wegge Keller wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 02/15/2012 02:30 PM, Anders Wegge Keller wrote:
> 
>>>  If it quacks like a duck, walks like a duck and swims like a duck, it
>>> probably is a duck, no matter how you dress it up. 
>>
>> Well, that works both ways - labeling it a prejudice doesn't make it
>> cease to be a well-justified judgment.
> 
>  Yoy have missed the point. I'm talking about cases like
> 
>  int debug_level;
> 
>  versus:
> 
>  static int debug_level
>  int get_debug_level(void) { return debug_level; }
>  void set_debug_level(int lvl) { debug_level = lvl; }

That's just a global dressed up in fancy clothes. It has all of the
disadvantages of a global, while being unnecessarily more complicated
than defining a global. If the setter function at least implemented some
kind of validity test on the new level, the example would make a little
more sense, but I had not considered that you were arguing against this
kind of idea.

>  I'm not trying to justify "All data should be global", as you seem to
> imply. I'm questioning "No data should be global". There is a world
> between those two statements.

I'd argue for "little, if any, data should be global". The only objects
that should have external linkage are those which will be used almost
everywhere in a program, and in my experience there aren't many of
those. If there are, poor design is usually to blame. To take your
example, I could quite easily imagine wanting to have different debug
levels in different parts of the program, which would make a single
global debug level inappropriate.

..
>  Try implementing GNU ls without globals. I know that the whole lot
> are statics, since the code is in just one TU, but imagine something
> of a similar magnitude then. The first few levels of functions will
> have prototypes of several pages.

I don't have time to implement the entirety of ls; if the sheer
complexity of ls is your point, then I won't be able to address it
directly. If there's some particular feature of ls that you think
requires use of globals, I could possibly spare time to implement a
simplified version providing only that feature.
-- 
James Kuyper

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


#17401

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 23:10 +0100
Message-ID<87ty2r929y.fsf@huddi.jernurt.dk>
In reply to#17398
James Kuyper <jameskuyper@verizon.net> writes:

> On 02/15/2012 03:30 PM, Anders Wegge Keller wrote:

> That's just a global dressed up in fancy clothes. It has all of the
> disadvantages of a global, while being unnecessarily more complicated
> than defining a global. 

 I'm happy to see that I managed to make myself clear. But sadly, I've
seen text books and style guides that advocates exactly this pattern.

 ...

>>  I'm not trying to justify "All data should be global", as you seem to
>> imply. I'm questioning "No data should be global". There is a world
>> between those two statements.
 
> I'd argue for "little, if any, data should be global". The only
> objects that should have external linkage are those which will be
> used almost everywhere in a program, and in my experience there
> aren't many of those.

 Apart from our embedded code, most of what I write for a living are
event-driven processes, that do a lot of IPC with each other. That
gives quite a lot of state, that either has to be a global, or be
dressed up as something else with the same properties, as the naive
example from last post.

> If there are, poor design is usually to blame. To take your example,
> I could quite easily imagine wanting to have different debug levels
> in different parts of the program, which would make a single global
> debug level inappropriate.

 Actually you have CHAR_BIT * (sizeof(int)/sizeof(char)) debug
masks. If that isn't enough, the process should probably be split into
two or more parts that are a bit more focused.

>>  Try implementing GNU ls without globals. I know that the whole lot
>> are statics, since the code is in just one TU, but imagine something
>> of a similar magnitude then. The first few levels of functions will
>> have prototypes of several pages.
 
> I don't have time to implement the entirety of ls; if the sheer
> complexity of ls is your point, then I won't be able to address it
> directly.

 I stated ls as an antithesis to

   "Variables which are local to main() and are passed by a pointer
    to subroutines need not be passed to all subroutines, but only
    the ones that actually need to have access to those variables, and
    that could be a different set of subroutines for different
    variables."

 Dividing the whole set of options into structs that are passed on a
stict "need to access"-basis for each individual function called from
main() will in effect lead to passing almost any command line option
as a separate argument down the call graph from main().

-- 
/Wegge

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

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


#17405

FromMalcolm McLean <malcolm.mclean5@btinternet.com>
Date2012-02-15 15:50 -0800
Message-ID<65e1cf75-2eaf-4cd9-b1ff-37401d59465a@eb6g2000vbb.googlegroups.com>
In reply to#17401
On Feb 15, 10:10 pm, Anders Wegge Keller <we...@wegge.dk> wrote:
>
>  Dividing the whole set of options into structs that are passed on a
> stict "need to access"-basis for each individual function called from
> main() will in effect lead to passing almost any command line option
> as a separate argument down the call graph from main().
>
Depends on the program. If you allow a "language" parameter for a text-
intensive interactive program, then yes, pretty much everything will
want to access the language the user has chosen. On the other hand if
you allow the user to specify the name of the output file, that only
needs to be passed to the routine that actually calls fopen(), which
might well be main() itself.


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


#17413

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-02-15 19:50 -0500
Message-ID<jhhjru$p82$1@dont-email.me>
In reply to#17401
On 02/15/2012 05:10 PM, Anders Wegge Keller wrote:
> James Kuyper <jameskuyper@verizon.net> writes:
> 
>> On 02/15/2012 03:30 PM, Anders Wegge Keller wrote:
...
>>>  Try implementing GNU ls without globals. I know that the whole lot
>>> are statics, since the code is in just one TU, but imagine something
>>> of a similar magnitude then. The first few levels of functions will
>>> have prototypes of several pages.
>  
>> I don't have time to implement the entirety of ls; if the sheer
>> complexity of ls is your point, then I won't be able to address it
>> directly.
> 
>  I stated ls as an antithesis to
> 
>    "Variables which are local to main() and are passed by a pointer
>     to subroutines need not be passed to all subroutines, but only
>     the ones that actually need to have access to those variables, and
>     that could be a different set of subroutines for different
>     variables."
> 
>  Dividing the whole set of options into structs that are passed on a
> stict "need to access"-basis for each individual function called from
> main() will in effect lead to passing almost any command line option
> as a separate argument down the call graph from main().

I had intended some judgment to be used; need-to-access must always be
traded off against other issues. Since I assumed that your challenge was
based upon the complexity of ls, I haven't bothered to give the design
any thought; but I would expect from previous experience that many of
the options would have corresponding data that must be passed with them,
and would therefore be grouped together in the same structure. In many
cases it will be convenient to tell a subroutine that a given option is
not turned on, by passing a null pointer as the argument which would
otherwise point to the data associated with that option.
-- 
James Kuyper

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


#17444

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-16 14:36 +0100
Message-ID<871upu99ys.fsf@huddi.jernurt.dk>
In reply to#17413
James Kuyper <jameskuyper@verizon.net> writes:

> On 02/15/2012 05:10 PM, Anders Wegge Keller wrote:

>>  Dividing the whole set of options into structs that are passed on
>> a stict "need to access"-basis for each individual function called
>> from main() will in effect lead to passing almost any command line
>> option as a separate argument down the call graph from main().
 
> I had intended some judgment to be used; need-to-access must always
> be traded off against other issues.

 I agree. Bu if - as I guess is the case for ls - about three quarters
of the options have to be propagated to three quarters of the code, if
not to provide a nightmarish complex call graph, we might as well
consider those options globals in all but name.

> In many cases it will be convenient to tell a subroutine that a
> given option is not turned on, by passing a null pointer as the
> argument which would otherwise point to the data associated with
> that option.

 Up to a limit. I've seen code evolving over time, until you end up
with a call like this:

 maniPrepareForHost (parcel_data, TRUE, FALSE, FALSE, TRUE, TRUE);

 I guess that it would be equally painfull to guess what the function
did, if there were two NULL's instead.

-- 
/Wegge

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

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


#17435

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-02-16 03:29 -0800
Message-ID<b38f672c-07e6-49f2-89a0-6518d2388962@c21g2000yqi.googlegroups.com>
In reply to#17378
On Feb 15, 6:25 pm, James Kuyper <jameskuy...@verizon.net> wrote:
> On 02/15/2012 12:25 PM, Anders Wegge Keller wrote:
> > Malcolm McLean <malcolm.mcle...@btinternet.com> writes:


> >> But if we can assume that fopen() and printf() work by magic,

ok!

> >> 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.

agreed

> >  That is global state in my book.

it's a jolly funny defintion. Yes its global state, but it isn't a
"global". The only people taht see it are those that need to. It makes
reasoning about the program easier and avoids certain classes of
error. Testing is simplified. Extension of the program is eased (see
the story of The Document by another poster).

> If that counts as global state, then storing global state in global
> variables is clearly not necessary.

quite

> >  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, ...
>
> Your use of "just" and "baaad" implies that you think that the idea that
> globals are bad is an unjustified prejudice, rather than the
> well-justified judgment that it actually is. Are you actually unaware of
> the problems that they can cause?

logically the function looked like this

void f (T p1, T p2);

but someone had decided multiple parameters were expensive (it even
said so in the programming standards).

So it was implemented like this

extern T fp1;
extern T fp2;
void f (void);

Then code like this was written

fp1 = x;
fp2 = y;
f();
g();
fp1 = z;
f();

which was fine until g() needed f() and updated fp2. I'm happy to say
it was my boss who wrote the "optimised" code above.

> > ... 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.
>
> n
> The key problem with global variables is visibility; by being visible
> everywhere, they can be affected by anything, which can make it
> difficult to determine what part of the program caused those variables
> to have their current value, or what part had it's behavior affected by
> the value.

which is one of the attractions of ADTs and OOP

> Variables which are local to main() and are passed by a
> pointer to subroutines need not be passed to all subroutines, but only
> the ones that actually need to have access to those variables, and that
> could be a different set of subroutines for different variables. Making
> information available to a subroutine only on a "need to know" basis is
> good software design. It can be overdone, but that's seldom a real-world
> problem.

I've worked on programs that were nearing MLOC. I'd hate it if all
"global state" were globally visible.

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


#17404

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-15 23:37 +0100
Message-ID<87pqdf910b.fsf@huddi.jernurt.dk>
In reply to#17373
ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Anders Wegge Keller <wegge@wegge.dk> writes:
> >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?
> 
>   Global state is something else than a global variable.

 No matter how elaborate you wrap it up, there will be a variable or
other storage object underneath in the end. And if direct access to a
global variable is a performance penalty, I fail to see how wrapping
them in another layer is going to help matters.

-- 
/Wegge

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

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


#17407

FromKaz Kylheku <kaz@kylheku.com>
Date2012-02-16 00:23 +0000
Message-ID<20120215162150.638@kylheku.com>
In reply to#17373
On 2012-02-15, Stefan Ram <ram@zedat.fu-berlin.de> wrote:
> Anders Wegge Keller <wegge@wegge.dk> writes:
>>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?
>
>   Global state is something else than a global variable.
>
>   Most programs don't have a global state. For example, when I
>   call a library function, such as »rand()«, whatever »global
>   variables« I declare in my application won't be visible by
>   »rand()«. So they are not global in the sense that they are
>   visible from /every/ part of the program: »rand()« is a part
>   of my program, yet does not see them.

You're bending the definition of global variable beyond what is reasonable. Any
function that simply does not mention a variable X does not see that variable.

X does not have to be mentioned in every scope in order to be considered
global.

Of course a standard library function like rand isn't going to contain
unresolved references to globals in your program.

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


#17410

FromAnders Wegge Keller <wegge@wegge.dk>
Date2012-02-16 01:29 +0100
Message-ID<87fweb8vte.fsf@huddi.jernurt.dk>
In reply to#17407
Kaz Kylheku <kaz@kylheku.com> writes:

> You're bending the definition of global variable beyond what is
> reasonable. Any function that simply does not mention a variable X
> does not see that variable.

 If directly acessing a global variable inside a loop is bad for
performance, then so is acessing any other global object hidden even
further.

-- 
/Wegge

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

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


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

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


csiph-web