Thread: dark side of global variables

  1. #1
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300

    dark side of global variables

    I was just reading some commentary/documentation and came across this:

    (after all, we do not want to go down the road of global variables, which will inevitably lead to the Dark Side, do we?)

    I'm as new to C as I am to cboard (is this issue consistent amongst all languages? I sense that it is...) but I really like global variables, such as flags, etc. -- buffers even!

    So why do some people drops hints, vis. global variables are for losers?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    They have their place, just like anything.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Many API's use globals and just hide them with calls to functions. Of course one downside to globals is thread-safety. But even then you can tinker with your type declaration to make things thread safe.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by master5001 View Post
    Of course one downside to globals is thread-safety.
    See, I just knew this meant "dark path"...

    Thanks master5001.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by master5001 View Post
    But even then you can tinker with your type declaration to make things thread safe.
    You mean things like "volatile"? That doesn't make anything "safer" - it makes the compiler not optimize the read/write operations to the data item (and in later versions of MS compilers "lock" the data access for read-modify-write operations). It does not fix this:
    Code:
    char *somefunc(int x)
    {
        static char buffer[100];
        sprintf(buffer, "%d", x);
        return buffer;
    }
    Call this function from two different functions with different values - then print the string - guess what: both threads will possibly print the same thing, and sometimes print "the wrong strings" value.

    Volatile, or just about any other "compiler" solution will not solve this.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I'm gonna stick it out with forks and pipes anyway.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    The larch
    Join Date
    May 2006
    Posts
    3,573
    I don't think thread-safety is the only issue.

    Overuse of globals simply lower the quality and robustness etc of your code to the point that it becomes completely unreadable/uncomprehensible for others and even yourself in a couple of months - if every piece of code potentially depends on any other piece of code, the chunks of code that you need to be able to follow become too large compared to nice functions that use arguments/return values properly. I would estimate at least 99% of globals in beginners' code are completely unneeded.

    For me, globals are more acceptable as systemwide constants, and perhaps some API sometimes requires to use some.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by anon View Post
    the chunks of code that you need to be able to follow become too large compared to nice functions that use arguments/return values properly.
    Well, really the chunks are the same size, anon, the difference is usually that you are passing around a pointer. There is a certian neatness to this, but it certianly doesn't add to comprehensibility (unless the reason is that this is so dominant a normative practice for you).

    w/r/t such aesthetics, balancing in a use of globals reduces the degree to which you have to pass anything at all. One one hand, I guess you could end up with nothing but void functions that have no() arguments. On the other, the functions could all end up with 3-5 arguments, the last two of which are always the same BUFFER and struct (or element of either) anyway
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    It really depends on what you re doing.
    MK27 and anon both have a point. If you have one buffer and 3 flags you probably want them global. If you have 20 flags and 30 buffers though it will get confusing. So you should organize your data more. People (including me) tend to think "this variable has to have a bigger scope so this two functions can both use it". And, voila, a global variable. The thing is that they spawn quickly.
    Of course if you have 30 buffers and 30 functions that each one uses one buffer then there is no confusion. So it really depends on the code.
    The sure thing is that globals CAN create a mess so they have to be treated carefully and avoided when not necessary.

    Besides you cannot force chock without the dark side

  10. #10
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You should not be using globals as replacement for arguments to a function.

    By passing a variable to a function, you know that function will modify that argument. If you have global variables, you do not know which function may modify that, without searching throughout the code. Passing pointers indicate that the function may change the value of some variable.

    Globals also prevent your code from being extended. What if you have ONE input file variable, and all of a sudden you feel that you need to be able to read in two different input files with your existing functions - you'd have to change your code around: close the first file and open the second file, or introduce some variable/parameter to know which input file to use, or start passing the file around.

    If a function always has the same 2-3 parameters, perhaps those should go into a struct, so that it becomes one paramater instead of 2-3.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  11. #11
    POeT GuY Matus's Avatar
    Join Date
    Feb 2008
    Location
    Bz
    Posts
    235
    Quote Originally Posted by matsp
    You mean things like "volatile"? That doesn't make anything "safer" - it makes the compiler not optimize the read/write operations to the data item (and in later versions of MS compilers "lock" the data access for read-modify-write operations). It does not fix this:
    How about:

    Example:
    Code:
    static __declspec(thread) int cornedbeeKeepsBlockingMatt = 3;
    , so whats up with the banning of Matt lately cornedbeek, sounds harsh!
    PoEms R InsPiRatiOns of LIfE ExpErienCes!!


  12. #12
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Matus View Post
    How about:

    Example:
    Code:
    static __declspec(thread) int cornedbeeKeepsBlockingMatt = 3;
    , so whats up with the banning of Matt lately cornedbeek, sounds harsh!
    That does make the variable a non-global, as it's now a Thread-Local-Storage (TLS) variable - and I much prefer to not use compiler-specific extension to make TLS work - as most OS's and compilers support TLS, but no other compiler than MS supports this keyword (hence the __ to indicate that it's non-standard).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  13. #13
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by matsp View Post
    If you have global variables, you do not know which function may modify that, without searching throughout the code. Passing pointers indicate that the function may change the value of some variable.
    Isn't searching through the code necessary from time to time? Plus all the globals are at the top with the function prototypes! True, without searching for the variable, you wouldn't be able to connect it with a particular function. But everything is fine with the compiler anyway.
    On the other hand, a pointer doesn't have to have the same name all the time, so it's bound to change.

    Globals also prevent your code from being extended. What if you have ONE input file variable, and all of a sudden you feel that you need to be able to read in two different input files with your existing functions - you'd have to change your code around
    That's a good point. But I don't think it's so dependant on the use or non-use of global variables as you are trying to imply.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  14. #14
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by MK27 View Post
    Isn't searching through the code necessary from time to time? Plus all the globals are at the top with the function prototypes! True, without searching for the variable, you wouldn't be able to connect it with a particular function. But everything is fine with the compiler anyway.
    On the other hand, a pointer doesn't have to have the same name all the time, so it's bound to change.
    Yes, but you only need to look at the code where the variable originates and then follow it through the call-chain until the variable isn't being used any more. Most of the time, that's only half a dozen or so functions - not always, and not in very large projects (that's when IDE's come in handy, as there is usually a way to "show me the call-tree of this function", etc).


    That's a good point. But I don't think it's so dependant on the use or non-use of global variables as you are trying to imply.
    If you pass in the FILE * that you are reading your data from, then you don't have to change the function you are calling - only the original call to read from the second file needs to be added somewhere (and of course opening, closing, etc the second file - but that has to be done either way).

    Obviously it does depend on what you are doing with the file and it's data - but it's never harder if you pass in a parameter with something - it may be harder if you use a global variable.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  15. #15
    POeT GuY Matus's Avatar
    Join Date
    Feb 2008
    Location
    Bz
    Posts
    235
    Quote Originally Posted by matsp
    That does make the variable a non-global, as it's now a Thread-Local-Storage (TLS) variable - and I much prefer to not use compiler-specific extension to make TLS work - as most OS's and compilers support TLS, but no other compiler than MS supports this keyword (hence the __ to indicate that it's non-standard).
    While TLS is not standard, it is certainly an option that defies the problems posed by multi-threading without simply hoping volatile will save the day. I never said I was pro-globals. I am simply offering solutions posed by the original poster's scenario.
    PoEms R InsPiRatiOns of LIfE ExpErienCes!!


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 08-06-2008, 09:59 AM
  2. Avoiding Global variables
    By csonx_p in forum Windows Programming
    Replies: 32
    Last Post: 05-19-2008, 12:17 AM
  3. Use global variables or pointers?
    By RealityFusion in forum C++ Programming
    Replies: 5
    Last Post: 09-22-2005, 08:47 PM
  4. Global variables.. how bad?
    By punkrockguy318 in forum C++ Programming
    Replies: 19
    Last Post: 11-30-2003, 10:53 PM
  5. global variables
    By rdnjr in forum Linux Programming
    Replies: 0
    Last Post: 01-07-2003, 10:28 AM

Tags for this Thread