Stop with the global variables Jules


#1

Please NO MORE of this!

We already have enough issues with order of initialization and destruction of objects with static storage duration. Why keep adding to it? Users are already complaining. We need fewer of these globals not more. If you look at beast I provide a solution (SharedSingleton + AtExitHook).

What happens when someone else wants to create an object with static storage duration that uses Uuid::null in some constructor? It fails.


#2

Ah, you know, you're right there - I was in a hurry when I wrote that, and it'd work just as well as a static method.


#3

What happens when someone else wants to create an object with static storage duration that uses Uuid::null in some constructor? It fails.

Worse than that - it might or might not fail, and if it doesn't fail, it might or might not fail later when you make some unconnected change and the compiler/linker decides to pick a different order of construction/destruction!

devil

The combination of informed contributors like TheVinn and a responsive BDFL is what makes Juce so very effective (I'm back on C++ this month and it's such a treat...)


#4

Does this hold true for String::empty as well?

If it's so, it's very dangerous because there are probably other static objects that make use of String::empty in their constructors...


#5

Don't panic! Vinnie isn't wrong, but he's over-dramatising the dangers somewhat.

If it's so, it's very dangerous because there are probably other static objects that make use of String::empty in their constructors...

Anything that's complex enough to use String::empty in its constructor is definitely not a good candidate for use as a globally-scoped static! If you think you may have done anything like that in your code, then it's time to do some serious code-reviewing!

The rule for staying safe is simple: Always use function-scoped statics, which will only get constructed when the function is called, i.e. after main() has been invoked and all globals have been constructed.


#6

Anything that's complex enough to use String::empty in its constructor is definitely not a good candidate for use as a globally-scoped static! If you think you may have done anything like that in your code, then it's time to do some serious code-reviewing!

I was thinking about the UnitTest subclasses I've added in various compilation units, following the example given by JUCE itself. It all works fine by now, but I cannot guarantee that none of it uses a String as its member (which could be initialised to a String::empty) upon creation. Better if I check about that?

The rule for staying safe is simple: Always use function-scoped statics, which will only get constructed when the function is called, i.e. after main() has been invoked and all globals have been constructed.

Fair enough. In such case, what is the rule for the destruction of such function level static objects?


#7

Well, unit tests are a bit of a special case, because if they don't work, then you'll just see it in your debug build, and it's not a big deal to work out why.

But if you're actually putting unit tests into code that you're shipping to customers, then I certainly wouldn't advise using statics for the classes like I've done! My motivation was just to simplify the way that it builds a list of all the available tests, to avoid having to manually maintain a list of them somewhere.

..although having said that, if your unit test classes don't actually contain any members (and there's no reason why they should do, as they should really just create local objects to use when the test runs), then I think it's absolutely safe to do it like I've done.

Likewise, don't get default-constructed strings confused with String::empty. It's perfectly safe to use a default-constructed String anywhere, even in statics.


#8

Destruction of function scoped static variables are in the reverse order they were constructed, acc. to C++ standard.

/R