• (cs) in reply to Tim Smith

    Singletons are just a global variable in sheep's clothing.

    I just have to disagree with that. Singletons solve several very important problems of global variables, all related to access control. Global variables are all necessarily globally writable by any module, and thus introduce difficult to track modification links. With a singleton, you encapsulate the data in a far stricter interface through which all modifications must go through. This makes it much easier to find when a global is being modified. The second issue the singleton solves is that of instance control. Some objects are necessarily designed to exist as one instance and one instance only in a process. Whether it be the application object with its event loop, a display object, or whatever, a singleton class can enforce the object's uniqueness within the program through static checking by the compiler, making it impossible for some idiot to define two application objects and then wonder why his event loop doesn't work all of a sudden.

  • David (unregistered)

    Funnily enough, this looks a bit like a design pattern I use a lot - caching a computed value. Of course I don't cache external globals; I cache the result of an external function such as a SQL lookup, where the function is slow, and has the same result every time it runs. This can make a major difference to run time.

    I am often surprised how little use most programmers make of caching. It can easily make the difference between microseconds and milliseconds per operation, which matters when you're doing it millions of times (e.g. per record on a big dataset, or per web page view when slashdotted :-).

  • (cs)

    Ok, I'm a newb and I ask a lot of stupid questions, but what exactly is this doing? Isn't it just returning whatever the value is for the global variable? Couldn't they just look at what the global variable has in it instead? Isn't that what makes them global (access from anywhere)?

    Either I'm stupid or this is stupid, but either way it makes my head hurt.

  • AdT (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++)

    The real WTF is that you actually seem to believe that statically allocated variables were inefficient.

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

    Ah, yes, but if the variable is of a POD (plain ol' data) type and the initializer is a constant expression, the compiler is absolutely entitled to throw out the runtime initialization and put the initializer value into the data segment (rsp., if the initializer would be represented as all zero bytes, it could be put into .bss). In both cases, the memory location holding the variable's value would typically be initialized either when the program is loaded, or when the corresponding memory page is first accessed, depending on how "lazy" the OS's executable loader is.

  • JoLeQ (unregistered)

    I was debugging some code for Hi Speed data capture a few years ago. This was code I took over from a previous programmer. The code captured data from multi-channel PCM sources. The analysts using the data were asking me why blocks of zeroes would appear periodically in the data when it wasn't possible for this to be true. I was new to OOP and didn't understand that each instance of a class shares the same static declared variables. The data buffer for each channel was getting set to zero after the processing code was finished with it thus clearing the buffer for all! Once I understood about static variables and classes, I removed the static declaration and no more zeroes in the data!

  • (cs) in reply to Dave
    Dave:
    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.

    In C++, perhaps, but not in C:

    ISO 9899:1999 6.2.4 #3:
    An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
    (My emphasis.)

    In any case, no conforming C program could distinguish between initialization prior to program startup and initialization immediately before first reference, since C only allows constant initializers.

    Of course (as usual) we don't know what language this snippet is supposed to be.

  • Guildenstern (unregistered)
    Zygo:
    ...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. (...)

    This code looks like non-ansi-C like we see it in embedded systems. That supposes that, there is a boolean type (which is not part of ansi-c. Maybe there is a define and the booleans are actually int or short). This C compilers are sometimes pretty buggy though you have to debug in assembler. A friend discovered that his global variables were accessed wrong. That was pretty similar to this problem.

    I guess this structure function will always return bGlobalBool despite the code doesn't say that. This happens when variables appear as pointers in asm. Then bGlobalBool and bBoolToReturn point the same value/address. This function is useful then to assure that this value is initialized

  • (cs)

    I once had to write code like this (but worse) because that's pretty much the only way to pretend you have functions on the TI 82 calculator basic.

  • truth seeker (unregistered) in reply to akatherder

    "All the code does is return bGlobalBool every time."

    No, it obviously does not do that. It returns whatever value bGlobalBool had the first time it was called.

    "Why write code that does nothing?"

    Why be a moron?

  • truth seeker (unregistered) in reply to Aaron

    "bInitialized will always be false when it's called"

    If you can't even read a few of the simplest lines of code in the known universe, why are you opening your yap?

  • truth seeker (unregistered) in reply to mattmoss

    "Because this does exactly the same"

    No it doesn't; it won't even compile unless bGlobalBool is a constant.

    Is WTF the place where all the programmers too stupid to even know they're stupid congregate?

  • truth seeker (unregistered) in reply to mattmoss

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

    So, mattmoron, do you really think that statics get initialized the first time their function is called? Shouldn't you know just a tiny teensy bit about how statics work before criticizing people who /do/ know how they work? The original code captures the value of the global on its first call -- none of the alternatives do. The code is the correct way to do what it is doing, and the people criticizing it are ignorant idiots.

  • truth seeker (unregistered) in reply to Aaron

    "if that's the intent, it's certainly not clear"

    Any decent programmer immediately recognizes the pattern and knows exactly what the code is doing -- and it's quite obvious that it was intended to do that. To the degree that the intention isn't clear, it's due only to some moron ripping the code out of context and posting it here.

  • truth seeker (unregistered) in reply to 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.

    Not in C you can't. And I wouldn't call it "refactoring" to hide explicit logic inside implicit runtime boilerplate. Isn't it intuitively obvious that "do X the first time Y happens" requires a conditional?

  • truth seeker (unregistered) in reply to anon

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

    This isn't rebinding to local scope -- can't you folks get anything right?

    Also, in many cases the compiler can do the rebinding for you. I realize that most Python users don't have a compiler -- but then they shouldn't be using Python if they are about speed. Anyone who employs "speed tricks" in Python is incompetent. Go find yourself a real language, like CL or ocaml.

  • truth seeker (unregistered) in reply to Dave

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

    Here's an MSDN article on C++ initialization of statics at block scope:

    http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx

    Notice that the compiler-generated code is almost identical to the manual code here, in what is most likely C, not C++, code. (C99 has bool, so that's not a distinction.) Of course, because of the context-free way this was posted, we can't know.

  • truth seeker (unregistered) in reply to vt_mruhlin

    "My Java's still kind of rusty. Does that copy the value of bGlobalBool into bBoolToReturn, or does it just create a reference."

    Um, bool is a primitive type, so a reference to what, exactly?

    "Why did I assume it was Java?"

    Incompetence? In java it's spelled "boolean", but more importantly there are no globals in Java.

  • truth seeker (unregistered) in reply to Zygo

    "C++ requires special scope-based, thread-safe initialization magic for static local variables"

    Bzzzt! Wrong! See http://blogs.msdn.com/oldnewthing/archive/2004/03/08/85901.aspx

    "The problem is that this code is not thread-safe. Statics with local scope are internally converted by the compiler into something like this: ... What you see here is not a compiler bug. This behavior is required by the C++ standard."

  • truth seeker (unregistered) in reply to Anonnmouse GuY

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

    Uh, yes, perhaps the compiler they were using was C compiler, not a C++ compiler, and perhaps this is C code, and not C++ code. Or perhaps the code once was or someday will be linked with C code.

    Sheesh.

  • truth seeker (unregistered) in reply to fluffy777

    "The joke is that static variables are just as inefficient as global variables."

    No, the joke is that the moron who posted this code had no idea what it does. Obviously no one was trying to save any speed, you his comments about speed, and yours, are idiotic.

  • truth seeker (unregistered) in reply to Zygo

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

    Is this an April Fool's joke? All address binding happens at load time -- O(1). Using a global symbol takes exactly the same time as using a static symbol, whether it's shared or not.

  • truth seeker (unregistered) in reply to Guildenstern

    "That supposes that, there is a boolean type (which is not part of ansi-c"

    Wrong, bozo; you're 8 years out of date.

    "I guess this structure function will always return bGlobalBool despite the code doesn't say that. This happens when variables appear as pointers in asm. Then bGlobalBool and bBoolToReturn point the same value/address."

    You are completely and utterly clueless. There are no pointers involved here, bool is a primitive type and is being copied.

  • truth seeker (unregistered)

    P.S. There's a good reason to think that this is C code, or is intended to be processed by a C compiler, or was written by a C programmer: void for an empty argument list is a definite C'ism, added to the language specifically so a compiler could distinguish between a declaration of a function with no arguments and a declaration lacking a prototype. Omit the void and gcc -Wstrict-prototypes says

    warning: function declaration isn’t a prototype

    whereas g++ doesn't even allow that flag because there's no such distinction in C++; in that language, declaring int foo(void) { ...} rather than int foo() { ...} is silly and pointless.

  • truth seeker (unregistered) in reply to truth seeker

    P.P.S.

    To illustrate that it really does matter in C:

    $ cat > foo.c int foo() { return foo(0); } $ gcc -c foo.c $ cat > foo.c int foo(void) { return foo(0); } $ gcc -c foo.c foo.c:1: error: too many arguments to function ‘foo’ $

  • zbigg (unregistered) in reply to FailedToEnterMyNameException
    FailedToEnterMyNameException:
    the real wtf is this discussion - i BET the author didnt think of singletons!
    The real WTF are those discussion participants who think of themselves as "a guru" writing essays and proving their ignorance ... as they don't understand static variable declarations :P

    And those who see any connotations of this "..." with singleton.

    Sham/ (not you FailedToEnterMyNameException) ... Alex, you too ?

  • (cs)

    Unless bGlobalBool is magically modified the code should just be.

    bool ReturnBool(void) { return bGlobalBool; }

    And case clossed.

  • rumpelstiltskin (unregistered) in reply to truth seeker
    truth seeker:
    Is WTF the place where all the programmers too stupid to even know they're stupid congregate?

    If you stick around on this site, you will learn, Monday, Wedensday, and Friday, the stupid mock the ignorant. Tuesday and Thursday, the ignorant mock the stupid. Weekends are a free for all.

  • AdT (unregistered) in reply to truth seeker
    truth seeker:
    No it doesn't; it won't even compile unless bGlobalBool is a constant.

    Is WTF the place where all the programmers too stupid to even know they're stupid congregate?

    It's always funny when ignoramuses call others stupid. The bool type and the true and false constants strongly suggest this is C++ code. Yes, there is a "(void)" parameter list, but this is perfectly acceptable in ISO C++ and equivalent to the empty parameter list. In C++, however, initializers of static storage variables do not have to be constant expressions.

    truth seeker:
    So, mattmoron, do you really think that statics get initialized the first time their function is called?

    Indeed, truthseekermoron, why don't you seek a little truth and take a (free!) peek at the C++ 98 draft standard and find out how static initializers work in C++?

    C++98 WD:
    6.7/4 A local object of POD type (3.9) with static storage duration initialized with constant-expressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects 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;

    Emphasis added to help the illiterate.

    truth seeker:
    The code is the correct way to do what it is doing, and the people criticizing it are ignorant idiots.

    Ha ha ha, whoever lives in a glass house shall cast the first stone, isn't it?

  • AdT (unregistered) in reply to truth seeker
    Guildenstern:
    That supposes that, there is a boolean type (which is not part of ansi-c.

    C99 has a _Bool type, actually.

    truth seeker:
    Or perhaps the code once was or someday will be linked with C code.

    Sheesh.

    Uh, yes, and how would that change the behavior of the C++ parts?

    Sheesh.

  • TonyG (unregistered) in reply to Aaron

    If this is C code, the static declaration instructs the compiler to allocate variables that are not automatic. They will retain their value between executions of the routine. See A4.1 'Storage Class' in the ANSI C definition. so bInitialized will retain its assigned value between invokations.

  • charon (unregistered)

    don't use singletons, they're globals too

  • AndreyT (unregistered) in reply to mattmoss

    That would be true for C++ code. Unfortunately, there'a no way to say whether the original snippet comes from C++ or C. The use of '(void)' in parameter declaration hints at C, not C++. The use of 'bool' hints at C++ or C99. So, it could be C89/90 code with user-defined 'bool', or it could be C99. In both flavors of C your variant would be ill-formed, since static objects can only be initialized with constant expressions.

  • (cs) in reply to anonymous

    "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) "

    tell you a better way to save one variable into another at a specified time? I don't think c handles such complex problems. If only there was support for things such as:

    bool savedValue = bGlobalBool

    yeah, that was tough.

Leave a comment on “Globally Local”

Log In or post as a guest

Replying to comment #:

« Return to Article