- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
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.
Admin
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 :-).
Admin
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.
Admin
The real WTF is that you actually seem to believe that statically allocated variables were inefficient.
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.
Admin
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!
Admin
In C++, perhaps, but not in C:
(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.
Admin
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
Admin
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.
Admin
"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?
Admin
"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?
Admin
"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?
Admin
"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.
Admin
"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.
Admin
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?
Admin
"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.
Admin
"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.
Admin
"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.
Admin
"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."
Admin
"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.
Admin
"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.
Admin
"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.
Admin
"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.
Admin
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.
Admin
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’ $
Admin
And those who see any connotations of this "..." with singleton.
Sham/ (not you FailedToEnterMyNameException) ... Alex, you too ?
Admin
Unless bGlobalBool is magically modified the code should just be.
bool ReturnBool(void) { return bGlobalBool; }
And case clossed.
Admin
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.
Admin
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.
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++?
Emphasis added to help the illiterate.
Ha ha ha, whoever lives in a glass house shall cast the first stone, isn't it?
Admin
C99 has a _Bool type, actually.
Uh, yes, and how would that change the behavior of the C++ parts?
Sheesh.
Admin
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.
Admin
don't use singletons, they're globals too
Admin
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.
Admin
"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.