Global vars versus pointers
Author |
Message |
dean #1 / 14
|
 Global vars versus pointers
Hi, say I have an int a and char *b which are defined and declared at main(), that I use throughout a program. Currently, I am passing down these variables as arguments from function down to a lower level function, to a lower one, and so on. However, some functions don't need to use these values, but just pass them onto functions nested inside them. This leads to functions with misleading declarations, and some redundant code. If I declared a and b as global, would this be a better approach? If I accessed a global each time, would it be performance hit? What if I copied the value of a global into a local variable in each function that used them? Say I did go the global way. Let's assume other_function() does not pass a and b to another function insde it. Should I do this: extern int a; extern char *b; void function(void) { do_stuff(); other_function(a, b); return; Quote: }
Or should I, from other_function(), do: extern int a; extern char *b; void other_function(void) { printf("%d and %s\n", a, b); return; Quote: }
Lastly, what effect would the static keyword have on global variables? I am guessing that it has no effect. Thanks for your time, Alex
|
Sun, 23 Feb 2003 10:44:41 GMT |
|
 |
Jack Klei #2 / 14
|
 Global vars versus pointers
comp.lang.c: Quote: > Hi, > say I have an int a and char *b which are defined and declared at > main(), that I use throughout a program. Currently, I am passing down > these variables as arguments from function down to a lower level > function, to a lower one, and so on. > However, some functions don't need to use these values, but just pass > them onto functions nested inside them. This leads to functions with > misleading declarations, and some redundant code. > If I declared a and b as global, would this be a better approach?
Maybe, maybe not. In general use of global variables should be kept to a bare minimum. It is far too easy to make mistakes or lose track of where, when, and why it is being changed. Quote: > If I accessed a global each time, would it be performance hit? What if > I copied the value of a global into a local variable in each function > that used them?
The answer to this question is 100% compiler and processor specific. On some architectures global variables are to access, on some locals are faster, on others there is no speed penalty. The same is true about the code size, some one way, some the other, others it makes no difference. [snip] Quote: > Lastly, what effect would the static keyword have on global variables? I > am guessing that it has no effect. > Thanks for your time, > Alex
Actually there is no such thing as "global" in C. There is external linkage, which means that the same object is accessed by the same name in the file that creates it and in other files where it is declared with the external keyword. As to the effect of the static keyword on variables defined at file scope, you are dead wrong. It changes them to internal linkage, so no other source file can refer to them by name. Jack Klein -- Home: http://jackklein.home.att.net
|
Sun, 23 Feb 2003 11:52:28 GMT |
|
 |
dean #3 / 14
|
 Global vars versus pointers
Hi Jack, I'll leave in the first chunk just so you don't have to go through the other messages. Quote: > >Currently, I am passing down > > these variables as arguments from function down to a lower level > > function, to a lower one, and so on. > > However, some functions don't need to use these values, but just pass > > them onto functions nested inside them. This leads to functions with > > misleading declarations, and some redundant code. > > If I declared a and b as global, would this be a better approach? > Maybe, maybe not. In general use of global variables should be kept > to a bare minimum. It is far too easy to make mistakes or lose track > of where, when, and why it is being changed.
OK, yes or no: does what I describe above sound like bad practice? I would really like to know now in order to change the code before I implement other features using the same principle of passing arguments recursively through functions. Quote: > As to the effect of the static keyword on variables defined at file > scope, you are dead wrong. It changes them to internal linkage, so no > other source file can refer to them by name.
static int b; int main(void) { ... Quote: }
void func(void) { ... Quote: }
Just to clear this up, you are saying that b will be visible to main() and func(), but not to other files if I try to link externally? Regards, Alex
|
Sun, 23 Feb 2003 12:30:53 GMT |
|
 |
Jack Klei #4 / 14
|
 Global vars versus pointers
comp.lang.c: Quote: > Hi Jack, > I'll leave in the first chunk just so you don't have to go through the other > messages. > > >Currently, I am passing down > > > these variables as arguments from function down to a lower level > > > function, to a lower one, and so on. > > > However, some functions don't need to use these values, but just pass > > > them onto functions nested inside them. This leads to functions with > > > misleading declarations, and some redundant code. > > > If I declared a and b as global, would this be a better approach? > > Maybe, maybe not. In general use of global variables should be kept > > to a bare minimum. It is far too easy to make mistakes or lose track > > of where, when, and why it is being changed. > OK, yes or no: does what I describe above sound like bad practice? > I would really like to know now in order to change the code before I > implement other features using the same principle of passing arguments > recursively through functions.
In general, don't use global variables unless you have a very specific need to do so. If you are not sure it is probably better _not_ to use them. As for worrying about performance, it sounds like you are nowhere near that point. Design and implement your program using the safest, clearest code you can. When it is working properly you can decide whether its speed is acceptable or not. Then you can use a tool like a profiler to find out where the real bottlenecks are and spend the effort on optimizing where it will do the most good. Unless you call a function repeatedly in a loop a large number of times, the impact of passing a few extra arguments is not likely to be one of those bottlenecks. If the variables that are needed in many, but not all, of your function hierarchy are closely related you can consider defining a structure to hold them, then you can pass a single pointer to that structure through your function chain in place of several separate variables. Quote: > > As to the effect of the static keyword on variables defined at file > > scope, you are dead wrong. It changes them to internal linkage, so no > > other source file can refer to them by name. > static int b; > int main(void) > { > ... > } > void func(void) > { > ... > } > Just to clear this up, you are saying that b will be visible to main() and > func(), but not to other files if I try to link externally? > Regards, > Alex
Yes, absolutely correct. If you have: static int b; at file scope in a file, all functions defined in that source file after the definition of b can use it. If you have: extern int b; In another source file and try to reference it, you will be unable to. Jack Klein -- Home: http://jackklein.home.att.net
|
Sun, 23 Feb 2003 12:56:35 GMT |
|
 |
dean #5 / 14
|
 Global vars versus pointers
Quote: > As for worrying about performance, it sounds like you are > nowhere near that point.
Well, I don't know what that is supposed to mean, but yes, you are right. My app is a file transfer client, so most of the time is spent either sending or receiving packets, or doing nothing. It being Un*x based, I am aiming for maximum portability, and nice, clean code. Therefore, I am not to concerned about architecture specific optimisations because, as you pointed out, what will be fast on one platform, will be the same or slower on another. Quote: > If the variables that are needed in many, but not all, of your > function hierarchy are closely related you can consider defining a > structure to hold them, then you can pass a single pointer to that > structure through your function chain in place of several separate > variables.
Yes, that's a very good tip. Thanks for the help, Alex
|
Sun, 23 Feb 2003 13:58:28 GMT |
|
 |
Richard Heathfiel #6 / 14
|
 Global vars versus pointers
Quote:
<snip> > static int b; > int main(void) > { > ... > } > void func(void) > { > ... > } > Just to clear this up, you are saying that b will be visible to main() and > func(), but not to other files if I try to link externally?
Yes, but I'm nervous about your use of the word "file". Whilst it is poor practice to put static data into header files, and it is also poor practice to #include C source, nevertheless both practices are legal (a bit like jumping down the stairs five at a time in your own home is legal - one day, it's going to hurt); thus, we should really be talking here about /translation units/, not files. b will be visible by name to main and func, but not to other translation units if you try to link externally. Note that you could do this: int *func(void) { return &b; Quote: }
thus getting round the static system and giving b a public interface by returning its address to any function in any translation unit that cares enough to call func(). This is easily avoided by simply not writing such functions! ;-) -- Richard Heathfield "Usenet is a strange place." - Dennis M Ritchie, 29 July 1999. C FAQ: http://www.eskimo.com/~scs/C-faq/top.html 65 K&R Answers: http://users.powernet.co.uk/eton/kandr2/index.html (32 to go)
|
Sun, 23 Feb 2003 13:57:42 GMT |
|
 |
mike burrel #7 / 14
|
 Global vars versus pointers
Quote:
> say I have an int a and char *b which are defined and declared at > main(), that I use throughout a program. Currently, I am passing down > these variables as arguments from function down to a lower level > function, to a lower one, and so on. > However, some functions don't need to use these values, but just pass > them onto functions nested inside them. This leads to functions with > misleading declarations, and some redundant code. > If I declared a and b as global, would this be a better approach? > If I accessed a global each time, would it be performance hit? What if > I copied the value of a global into a local variable in each function > that used them?
in terms of the 'evilness' continuum, global variables are about as evil as you can get. internal variables defined at file-scope are a little bit better. not to say that all global variables have to be evil, though. errno is sometimes a global variable, and it can work like that. what you're given up when you use a shared variable (either global or
a chunk of code and turn it into an "object". plus, it's much uglier if anyone ever wants to be able to add threads to your code. it comes down to you, though, what kind of trade-offs you want to make. personally, i never use global symbols unless i have to (damn you yacc!) simply because of the namespace pollution. -- /"\ m i k e b u r r e l l
X AGAINST HTML MAIL,
|
Sun, 23 Feb 2003 23:02:27 GMT |
|
 |
Eric Sosma #8 / 14
|
 Global vars versus pointers
Quote:
> in terms of the 'evilness' continuum, global variables are about as evil as > you can get. [...]
#include <stdio.h> int main(void) { puts ("Hello, world!"); return 0; } Exercise 1 (easy): Spot the global variable in this program. Exercise 2 (hard): Write an equivalent program without using global variables. Exercise 3 (essay question): Explain the nature of evil, and why people voluntarily sell their souls to the Devil now and then. --
|
Mon, 24 Feb 2003 22:32:42 GMT |
|
 |
Joona I Palast #9 / 14
|
 Global vars versus pointers
:> :> in terms of the 'evilness' continuum, global variables are about as evil as :> you can get. [...] : #include <stdio.h> : int main(void) { : puts ("Hello, world!"); : return 0; : } : Exercise 1 (easy): Spot the global variable in this program. There are lots of them. stdin, stdout, stderr for instance. You can't see them from the source code, but they are there, because of the #include <stdio.h> line. : Exercise 2 (hard): Write an equivalent program without using : global variables. Um. I'm going to try, but I might very well fail... here goes... void puts(char *s); int main(void) { puts("Hello, world!"); return 0; Quote: }
Notice no #include <stdio.h> line. That's the whole point. : Exercise 3 (essay question): Explain the nature of evil, and : why people voluntarily sell their souls to the Devil now and then. Evil is valuing yourself above others, even if gain to yourself causes harm to others. People voluntarily sell their souls to the Devil because of the promised benefits and their short-sightedness about the consequences. --
| Kingpriest of "The Flying Lemon Tree" G++ FR FW+ M- #80 D+ ADA N+++ | | http://www.helsinki.fi/~palaste W++ B OP+ | \----------------------------------------- Finland rules! ------------/ "It's time, it's time, it's time to dump the slime!" - Dr. Dante
|
Mon, 24 Feb 2003 23:00:57 GMT |
|
 |
Marco Naton #10 / 14
|
 Global vars versus pointers
Joona, Quote:
>> #include <stdio.h> >> int main(void) { >> puts ("Hello, world!"); >> return 0; >> } >> Exercise 2 (hard): Write an equivalent program without using >> global variables. > Um. I'm going to try, but I might very well fail... here > goes... > void puts(char *s); > int main(void) { > puts("Hello, world!"); > return 0; > }
The function puts() seems to return an integer and, however, you have not avoided to use global variables, even living in the library. Surely, the point is: "if you find GVs in a standard library, why can not you use them by yourself?" and the answer is "Yes, you can use them", since global variables are bad only if you use them badly (IMHO, the same as /goto/). Best regards, Marco
|
Mon, 24 Feb 2003 23:19:41 GMT |
|
 |
Phil Tregonin #11 / 14
|
 Global vars versus pointers
Quote:
> :> > :> in terms of the 'evilness' continuum, global variables are about as evil as > :> you can get. [...] > : #include <stdio.h> > : int main(void) { > : puts ("Hello, world!"); > : return 0; > : } > : Exercise 1 (easy): Spot the global variable in this program. > There are lots of them. stdin, stdout, stderr for instance. You can't > see them from the source code, but they are there, because of the > #include <stdio.h> line.
Can an implementation not do this in stdio.h? FILE *__stdin(void); #define stdin (__stdin()) or even FILE *__stdin(void); #pragma define_that_cant_be_undefined stdin (__stdin()) or other compiler magic. Is it legal to take the address of stdin? Phil T
|
Tue, 25 Feb 2003 00:47:15 GMT |
|
 |
Thomas M. Sommer #12 / 14
|
 Global vars versus pointers
Quote:
> :> > :> in terms of the 'evilness' continuum, global variables are about as evil as > :> you can get. [...] > : #include <stdio.h> > : int main(void) { > : puts ("Hello, world!"); > : return 0; > : } > : Exercise 1 (easy): Spot the global variable in this program. > There are lots of them. stdin, stdout, stderr for instance. You can't > see them from the source code, but they are there, because of the > #include <stdio.h> line. > : Exercise 2 (hard): Write an equivalent program without using > : global variables. > Um. I'm going to try, but I might very well fail... here goes... > void puts(char *s); > int main(void) { > puts("Hello, world!"); > return 0; > } > Notice no #include <stdio.h> line. That's the whole point.
If you don't #include <stdio.h>, the globals are still there; you just can't see them.
|
Tue, 25 Feb 2003 02:03:18 GMT |
|
 |
386s #13 / 14
|
 Global vars versus pointers
Quote: >If you don't #include <stdio.h>, the globals are still there; you just >can't see them.
Which is about as evil as you can get. <g> -- http://www.eskimo.com/~scs/C-faq/top.html The comp.lang.c FAQ "It is often impossible to accomplish the desired goal without using some degree of non-portable code." -Chris Torek
|
Tue, 25 Feb 2003 02:35:27 GMT |
|
 |
Lawrence Kir #14 / 14
|
 Global vars versus pointers
... Quote: >Can an implementation not do this in stdio.h? > FILE *__stdin(void); > #define stdin (__stdin()) >or even > FILE *__stdin(void); > #pragma define_that_cant_be_undefined stdin (__stdin()) >or other compiler magic. >Is it legal to take the address of stdin?
stdin, stdout and stderr are defined as "expressions" in the standard so are not lvalues, you can't take their addresses and your first suggestion is valid. For the second I think they should be undefinable. It follows from this that they aren't necessarily "global variables" although they behave a lot like them. -- -----------------------------------------
-----------------------------------------
|
Wed, 12 Mar 2003 03:00:00 GMT |
|
|
|