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 3 of 4 — ← Prev page 1 2 [3] 4 Next page →
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | Malcolm McLean <malcolm.mclean5@btinternet.com> |
|---|---|
| Date | 2012-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]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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]
| From | Kaz Kylheku <kaz@kylheku.com> |
|---|---|
| Date | 2012-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]
| From | Anders Wegge Keller <wegge@wegge.dk> |
|---|---|
| Date | 2012-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