• dkf (unregistered)

    Why? That's stupidity personified. Well, unless something called a global boolean is really something else, which would be far scarier still.

    True cargo-cult programming here.

  • sol (unregistered)

    #define FALSE 0;

  • Andy Goth (unregistered) in reply to sol

    I hope that semicolon is part of the joke...

  • Andy Goth (unregistered) in reply to dkf

    Nice Richard Feynman reference. The "cargo cult" concept has been very useful to me in understanding many of the WTFs I encounter from day to day, technical and nontechnical.

    Do I know you from the Tcl Wiki, or are you another DKF?

  • PeterE (unregistered)

    While the use of globals may be contentious the code presented doesn't seem like a WTF to me. It looks like a singleton design pattern that initialises the resource from a external location. Of course it is not a thread safe implementation - but given no context as to where the code came from this may or may not be a WTF.

  • dkf (unregistered) in reply to Andy Goth
    Andy Goth:
    Do I know you from the Tcl Wiki, or are you another DKF?
    You mean you think there might be another one of me? Scary! (Yes, I hang out on that wiki.)
  • akatherder (cs)

    All the code does is return bGlobalBool every time. Why write code that does nothing?

  • Andy Goth (unregistered) in reply to dkf

    "Scary" must be the word of the day. I wonder if it's one of the CAPTCHAs this site uses. (Mine was "howdy", probably in honor of the state in which I live.)

  • Tim Smith (unregistered)

    As someone already pointed out, this is just a common implementation of a singleton using stupid variable types.

    However, like this code, the vast majority of singletons I have seen over the years are just as dumb as this code because the implementor knew that "global variables are bad".

    As Sutter once said, "Singletons are just a global variable in sheep's clothing."

    Singletons have some important use cases, but they also have the same vast majority of design issues as global variables. Just different initialization characteristics.

  • T $ (cs)

    Global variables are bad because of the potential for naming conflicts (OHHHH, it's a JOOOKE, nevermind).

    Oh, I get the WTF now, it's because they didn't explicitly put an access modifier in there. It was so obvious!

  • Mike5 (unregistered)

    The goggles do nothing!

  • D (unregistered)

    Wow... I think i may need to steal that code... its so elegent. so amazing. so... so...

    Globals = Bad because when students use globals you come out with code like:

    int someNum = 0;

    foo(){ //some code here someNum = 1; bar(); //some more code here }

    bar(){ // some humanly unreadable code someNum = 2; // some more code that is humanly unreadable }

    TEACHER TEACHER... SOMENUM IS 2 FOR SOME WIERD-O REASON! I THINK COMPUTERS ARE OUT TO GET ME!

    And thats why, kids, global variables just may be the spawn of the devil!

  • Aaron (cs)

    It's not a singleton pattern because this code is all contained in a single method (hence the multiple references to "local" in the title and preamble). Thus, bInitialized will always be false when it's called, and as it was pointed earlier, the method will always return the contents of bGlobalBool. It really makes no difference that any of those locals happen to be declared static.

    Also interesting to note that even if this really did implement a singleton (which, if this is C code, would require bInitialized and bBoolToReturn to be uh, global), then it would be an incorrect implementation, because it would return the wrong value if bGlobalBool were ever changed after the first method call.

    So basically, out of sheer luck, the programmer managed to write a function that's merely pointless and not buggy or harmful. I would call this cargo cult programming as well - he thought he was writing a singleton because it sort of looked a bit like a singleton with the static declarations, but it's actually not even close.

  • H. Sluga (unregistered) in reply to Aaron

    bIninitialized won't always be false when it's called; it's static, so it will be false only the first time.

    There is potentially a side-effect-as-point-of-the-function here if bGlobalBool is an object with a (bool) cast.

  • dm (unregistered) in reply to Aaron
    Aaron:
    Thus, bInitialized will always be false when it's called, and as it was pointed earlier, the method will always return the contents of bGlobalBool. It really makes no difference that any of those locals happen to be declared static.

    bInitialized will only be false the first time the function is called (the state of static local variables is preserved between function calls) so this will always return whatever the value of bGlobalBool was the first time the function was called.

    I can think of easier ways to store the value of a variable...

  • mattmoss (cs) in reply to PeterE
    PeterE:
    While the use of globals may be contentious the code presented doesn't seem like a WTF to me. It looks like a singleton design pattern that initialises the resource from a external location. Of course it is not a thread safe implementation - but given no context as to where the code came from this may or may not be a WTF.

    Here, in part, is why it's a WTF... Because this does exactly the same:

    bool ReturnBool(void)
    {
        static bool bBoolToReturn = bGlobalBool;
        return bBoolToReturn;
    }
    

    Which is not quite the same as this:

    bool ReturnBool(void)
    {
        return bGlobalBool;
    }
    

    Since the latter will always return the current value of bGlobalBool, while the former (and the original post) return the value of bGlobalBool at the time of the first call.

    WTF knows what is really wanted... But at least the person writing it should have known how statics worked.

  • FailedToEnterMyNameException (unregistered)

    the real wtf is this discussion - i BET the author didnt think of singletons!

    CAPTCHA: gygax - wtf is that?

  • Ken (unregistered) in reply to FailedToEnterMyNameException
    FailedToEnterMyNameException:
    CAPTCHA: gygax - wtf is that?

    Gary Gygax was one of the original authors of the Dungeons & Dragons game system.

  • Aaron (cs)

    OK, I guess my C is worse than I thought. You're right, the static will be preserved. In which case, it really is buggy code because it's only guaranteed to return the correct value of the global variable the first time it's called. And if that's the intent, it's certainly not clear.

  • ZexVux (unregistered)

    This code might be correct if person, who wrote it, just want always return value bGlobalBool which was on the first call ReturnBool, because bGlobalBool can be changed latter.

  • sibtrag (cs) in reply to PeterE
    PeterE:
    It looks like a singleton design pattern that initialises the resource from a external location.

    Since software development is not my full-time job, I had never heard of the "singleton" design pattern. So, I did the usual Google search & found a Wikipedia article. It had the following delightful explanation:

    Wikipedia:
    The singleton pattern is implemented by creating a class with a method that creates a new language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.

    Now, there have been quite a few new programming languages created in the time since I studied programming...but having a method which creates new languages is a bit of overkill, IMO.

  • PeterE (unregistered) in reply to Aaron
    Aaron:

    Also interesting to note that even if this really did implement a singleton (which, if this is C code, would require bInitialized and bBoolToReturn to be uh, global), then it would be an incorrect implementation, because it would return the wrong value if bGlobalBool were ever changed after the first method call.

    Its a singleton that initialises from a global resource at the first time the routine is run. After the routine has been run then the global can be changed without affecting the internally saved value. This allows you modify the global during program execution and control when the internal copy is updated (which is really on program restart).

    Yes it is badly coded, but IMO it is functional.

    The problem with WTFs like this is there is no context. We don't know where the global comes from, why its being buffered like this or in how many locations this routine is being called from. The only thing you can say (as has previoulsy been pointed out) is that you can refactor the code to remove the "if" statement.

  • anonymous (unregistered)

    I'm sorry but I don't see what's wrong with that CodeSOD !!

    You guys miss the point.. This function will always return the VALUE THAT bGlobalBool HAD THE FIRST TIME the function is called

    If that's what the author intended, then it's fine, and you tell me how to do otherwise (in C in an encapsulated manner)

  • PeterE (unregistered) in reply to sibtrag
    sibtrag:
    Wikipedia:
    The singleton pattern is implemented by creating a class with a method that creates a new language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.

    Now, there have been quite a few new programming languages created in the time since I studied programming...but having a method which creates new languages is a bit of overkill, IMO.

    Gotta love Wikepedia .. If an infinite number of Monkeys with typewriters can produce Shakespeare in an infinite amount of time, then that qoute looks like 10 Monkeys in 1/2 hour.

  • dkf (unregistered) in reply to PeterE
    PeterE:
    Yes it is badly coded, but IMO it is functional.
    Yes, it looks that way to start with. But the problems run deeper than that. Firstly, there is no guarantee of when the global will be read, so who knows what value it will get. Secondly, they're not using double-checked locking, so either they're single-threaded or the behaviour is even less defined. Thirdly, there's a good chance that the previous points are moot because the global is actually constant in value in all practical senses, rendering this code a piece of valueless rococo voodoo.

    In short, either the code is pointless or its wrong.

  • Zylon (cs) in reply to FailedToEnterMyNameException
    FailedToEnterMyNameException:
    the real wtf is this discussion - i BET the author didnt think of singletons!

    CAPTCHA: gygax - wtf is that?

    It means that you're clueless. Typing your captcha was our first hint, but not knowing who Mr. Gygax is sealed the deal.

  • Aaron (cs) in reply to PeterE
    PeterE:
    Its a singleton that initialises from a global resource at the first time the routine is run. After the routine has been run then the global can be changed without affecting the internally saved value. This allows you modify the global during program execution and control when the internal copy is updated (which is really on program restart).

    Yes it is badly coded, but IMO it is functional.

    There is no indication that that's the intent, though. Of course it could be anonymization, but I'd expect to see a word like "buffer" or "cache" in there.

    It's not logical that the contents of a global variable (especially a primitive type) would be cached throughout the entire lifetime of an application, and since the variables are local to that method, there is no way they can ever get updated without restarting the program.

    This is either a horribly botched singleton implementation, or an even more botched MRSW implementation.

  • psmears (unregistered) in reply to Aaron
    Aaron:
    It's not a singleton pattern because this code is all contained in a single method (hence the multiple references to "local" in the title and preamble). Thus, bInitialized will always be false when it's called, and as it was pointed earlier, the method will always return the contents of bGlobalBool. It really makes no difference that any of those locals happen to be declared static.

    Also interesting to note that even if this really did implement a singleton (which, if this is C code, would require bInitialized and bBoolToReturn to be uh, global), then it would be an incorrect implementation, because it would return the wrong value if bGlobalBool were ever changed after the first method call.

    So basically, out of sheer luck, the programmer managed to write a function that's merely pointless and not buggy or harmful. I would call this cargo cult programming as well - he thought he was writing a singleton because it sort of looked a bit like a singleton with the static declarations, but it's actually not even close.

    Perhaps you should go re-read K&R: the "static" does make a difference (it effectively turns the local variables into globals), so this is a singleton (of sorts)...

  • noone (unregistered) in reply to mattmoss
    mattmoss:
    bool ReturnBool(void)
    {
        static bool bBoolToReturn = bGlobalBool;
        return bBoolToReturn;
    }
    

    ... the former (and the original post) return the value of bGlobalBool at the time of the first call.

    "the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified." So if the global variable is modified after program start (but before the function call), then your function will fail, while the original won't. Well OK, they'll work differently.

  • Sgt. Preston (unregistered) in reply to sibtrag
    Comment held for moderation.
  • the littlest hobo (unregistered) in reply to Sgt. Preston
    Comment held for moderation.
  • anon (unregistered)

    In Python, rebinding globals to a local scope is a well-known speed trick, indeed :-)

    (note: the speed gain may be less than zero if you have no fancy loops)

  • Dave (unregistered) in reply to noone
    noone:
    "the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified." differently.

    That quote from the MSDN Visual C++ article is a bit misleading as a static variable defined in a function may be allocated at startup but it is not initialized at startup. It is initialized when the function is first called.

  • Aaron (cs) in reply to psmears
    psmears:
    Perhaps you should go re-read K&R: the "static" does make a difference (it effectively turns the local variables into globals), so this *is* a singleton (of sorts)...
    Edit: Never mind, you just came late to the party and obviously didn't read the other comments. That point was already addressed.
  • vt_mruhlin (cs) in reply to akatherder
    akatherder:
    All the code does is return bGlobalBool every time. Why write code that does nothing?

    My Java's still kind of rusty. Does that copy the value of bGlobalBool into bBoolToReturn, or does it just create a reference. Even if it is copying it, that's still some wierdness. "This function returns whatever the value of bGlobalBool was when this function was first called."

    Addendum (2007-08-10 12:40):

    akatherder:
    All the code does is return bGlobalBool every time. Why write code that does nothing?

    My Java's still kind of rusty. Does that copy the value of bGlobalBool into bBoolToReturn, or does it just create a reference. Even if it is copying it, that's still some wierdness. "This function returns whatever the value of bGlobalBool was when this function was first called."

    Edit: Yeah that does look more like C. Why did I assume it was Java?

  • Reaver (unregistered)

    Nothing wrong with it, its just a bit mislabeled! ;D

    bool Latch(void) { static bool bLatchValue = false; static bool bLatchInitialized = false;

    if (bLatchInitialized == false)
    {
        bLatchValue = bGlobalBool;
        bLatchInitialized = true;
    }
    return bLatchValue;
    

    }

    Cheers!

  • Zygo (unregistered) in reply to PeterE
    PeterE:
    The only thing you can say (as has previoulsy been pointed out) is that you can refactor the code to remove the "if" statement.

    ...IF you can trust your compiler, and if you're coding in C++.

    Some of the compilers I stopped using years ago would get static local variable initialization wrong. Regardless of what the code says, static variables would be initialized to zero, especially in .so's. This would wreak havoc on non-trivial classes that expected their pointer members to be non-NULL.

    C doesn't have initialization of anything from non-const expressions, of course, so the if statement is required in that language.

    IIRC (I do have the ISO C++ standard, but I'm too lazy to read it today ;-) C++ requires special scope-based, thread-safe initialization magic for static local variables, but no such magic for globals, file-scoped statics, or static members. A lot of people don't know this, and assume that static local variables behave like all the other kinds of static-ish variables, which are initialized in undefined or implementation-defined order before main(). This is of course wrong, but writing with the 'if' statement works both ways.

  • Anonnmouse GuY (unregistered) in reply to mattmoss
    mattmoss:
    bool ReturnBool(void)
    {
        static bool bBoolToReturn = bGlobalBool;
        return bBoolToReturn;
    }
    

    Hmm, gcc 2.95,3.3,4.0.4,1 won't compile with that, gives me an error:

    error: initializer element is not constant
    Although, g++ 2.95,3.3,4.0.4,1 will compile it, and it acts the same as the original.

    Perhaps the compiler they were using gave them that error, because using the if/then that was in the original does work in GCC.

  • Anonnmouse GuY (unregistered) in reply to mattmoss
    mattmoss:
    bool ReturnBool(void)
    {
        static bool bBoolToReturn = bGlobalBool;
        return bBoolToReturn;
    }
    

    Hmm, gcc 2.95,3.3,4.0.4,1 won't compile with that, gives me an error:

    error: initializer element is not constant
    Although, g++ 2.95,3.3,4.0.4,1 will compile it, and it acts the same as the original.

    Perhaps the compiler they were using gave them that error, because using the if/then that was in the original does work in GCC.

  • SuperousOxide (cs) in reply to akatherder
    akatherder:
    All the code does is return bGlobalBool every time. Why write code that does nothing?

    Not quite, it returns the value that bGlobalBool had the first time the function is called. If bGlobalBool is later changed, this function will never notice.

  • Anonymous Pedant (unregistered) in reply to PeterE
    PeterE:
    sibtrag:
    Wikipedia:
    The singleton pattern is implemented by creating a class with a method that creates a new language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.

    Now, there have been quite a few new programming languages created in the time since I studied programming...but having a method which creates new languages is a bit of overkill, IMO.

    Gotta love Wikepedia .. If an infinite number of Monkeys with typewriters can produce Shakespeare in an infinite amount of time, then that qoute looks like 10 Monkeys in 1/2 hour.

    Actually, an infinite number of monkeys will produce Shakespeare in exactly as long as it takes to type the work in question. Comes to that, they'll produce an infinite number of copies. (Good luck finding one though....)

  • Kuba (unregistered) in reply to sibtrag
    Comment held for moderation.
  • Kuba (unregistered) in reply to PeterE
    PeterE:
    sibtrag:
    Wikipedia:
    The singleton pattern is implemented by creating a class with a method that creates a new language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation.

    Now, there have been quite a few new programming languages created in the time since I studied programming...but having a method which creates new languages is a bit of overkill, IMO.

    Gotta love Wikepedia .. If an infinite number of Monkeys with typewriters can produce Shakespeare in an infinite amount of time, then that qoute looks like 10 Monkeys in 1/2 hour.

    Nope. Consider yourself 100% clueless about how Wikipedia works. Big deal, so there are idiots out there who will wreck perfectly good entry for no reason... and then comes a fool like ya who has no clue, too.

    Cheers!

  • Zygo (unregistered) in reply to noone
    noone:
    "the static keyword specifies that the variable has static duration (it is allocated when the program begins and deallocated when the program ends) and initializes it to 0 unless another value is specified." So if the global variable is modified after program start (but before the function call), then your function will fail, while the original won't. Well OK, they'll work differently.

    OK, I got un-lazy and decided to look this up:

    ISO 14882 (6.7.4):
    An implementation is permitted to perform early initialization of [local objects that have non-const initializers or non-trivial constructors] with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope (3.6.2). Otherwise such an object is initialized the first time control passes through its declaration.

    In other words, the bBoolToReturn could contain either the value of bGlobalBool some time between program start and calling main(), or the value of bGlobalBool the first time ReturnBool is called, depending on the compiler. The C++ standard considers either to be correct.

    Yeouch!

  • Zygo (unregistered) in reply to Anonnmouse GuY
    Anonnmouse GuY:
    Hmm, gcc 2.95,3.3,4.0.4,1 won't compile with that, gives me an error:
    error: initializer element is not constant
    Although, g++ 2.95,3.3,4.0.4,1 will compile it, and it acts the same as the original.

    No surprise--you can't initialize global or static variables with non-constant values in C, period. Constructors are a C++ feature.

  • psmears (unregistered) in reply to Aaron
    Aaron:
    psmears:
    Perhaps you should go re-read K&R: the "static" does make a difference (it effectively turns the local variables into globals), so this *is* a singleton (of sorts)...
    Edit: Never mind, you just came late to the party and obviously didn't read the other comments. That point was already addressed.
    Hmm, I seem to be accessing the page through some sort of webcache that is introducing a delay... when I refreshed just before posting, yours was the last comment there :-/... sorry about that!
  • fluffy777 (cs)

    The joke is that static variables are just as inefficient as global variables. Did everyone ignore the sentence "gain all the benefits of global variables without hampering performance too much" ??

    Lemme explain for those who don't think in assembly (and still write code in C++):

    Static variables have static allocation, and global variables have static allocation: the runtime doesn't care about the artificial concept of "scope", which is all the code snippet introduces.

  • Billy Bob (unregistered)

    What if you were to reference a local variable with a far pointer??? How close is that variable

  • Darien H (unregistered)

    Regarding wikipedia, someone just did an edit and accidentally erased the words: "one. If the programming" so that two adjacent sentences ran together.

    Captcha: Sanitarium. "Is that where they're taking me? Because if it's cleaner than my home with the filthy filthy germs that are everywhere and oh god must keep scrubbing..."

  • Zygo (unregistered) in reply to fluffy777
    fluffy777:
    The joke is that static variables are just as inefficient as global variables. Did everyone ignore the sentence "gain all the benefits of global variables without hampering performance too much" ??

    Lemme explain for those who don't think in assembly (and still write code in C++):

    Static variables have static allocation, and global variables have static allocation: the runtime doesn't care about the artificial concept of "scope", which is all the code snippet introduces.

    Actually, that's not entirely true. Shared library runtimes care very much about the concrete concept of "visibility".

    ELF shared library symbols are visible (exported) by default (some would argue this is a WTF in itself, but it's the way ELF works). Global variables have externally visible symbols, which means that they must be resolved against the symbol table either at dynamic link time or on first use. That includes global variables that are both defined and used in the same shared library. ELF allows you to have the same global variable defined in multiple shared libs, but have all the libraries use a common instance of that variable. Accidental name collisions can occur, and when they do they usually ruin your day.

    Static variables, on the other hand, can be referenced by a simple offset from the start of the library's data section every time the variable is used. No symbol lookup is required, because there is no way the symbol could possibly be defined or used in another library in a way that refers to the same variable (that's what "static" means, after all). Symbol lookup is quite slow compared to integer addition, so avoiding lookup makes the code go faster. Even if the global symbol's address is cached after lookup (which of course it is), it's still very slightly slower to use than the static symbol. Also, dynamic linking time is proportional to the number of symbols in the library, so a static variable is cheaper at load time as well.

    Of course, non-exported global variables are just as fast as static variables. The linker treats such variables as global while building the library, then discards their symbols (so the variables appear to be static from the point of view of some code outside of the library) once all the objects in the library are built.

    If you're really evil, you can force the dynamic linker to do relocation on the shared library (which rewrites the library at dynamic load time so that it doesn't need to do symbol table lookups, but at the expense of longer startup time and more memory consumption). In that case, there is no difference between static and global variables any more (all references to them in the code have been replaced with absolute addresses), but the cost of this "optimization" is astronomical compared to the benefits in most cases.

    a.out shared libs solve this problem by fixing the address of every global or static variable ever defined. By anyone. Ever. Worldwide. Needless to say, this solution scales so badly that nobody bothers to use it any more.

    There are other ways to reduce the cost of global or static variables. For example, in theory function bar is faster, even if the code is identical except for replacing 'i' with 'my_i':

    int i;
    
    int foo() {
        // Determine address of i and keep a local reference to it
        int &my_i = i;
    
        // code that does lots of stuff with my_i
        // gets &i from the stack (1 loads + 1 add) each time
    }
    
    int bar() {
        // code that does lots of stuff with i
        // gets &i from the shared lib (2 loads + 1 add + 1 call + 1 return) each time
    }
    

Leave a comment on “Globally Local”

Log In or post as a guest

Replying to comment #:

« Return to Article