JUCE 6: why is a new default plugin project requiring "juce::" in front of everything?

Should we do the same with our own classes? I mean Include all of them in a custom namespace

This kind of thing:

using SomeType = juce::SomeType;

is useful if you’re giving something a different name for semantic reasons (e.g. using NumberOfPixels = std::uint32_t, or if you’re going to be using a type in many places and expect that you’ll want to change the type later for some reason.

But this form:

using juce::SomeType;

is something you should avoid completely.

Its only purpose is to save you typing, at the expense of cluttering the scope with imported symbols, and making your own code less clear.

Yes, if your code can be divided into module-like sections, it can help to split them up by namespace.

The main reason this helps is that if you have two modules, it’s best to minimise dependencies between them, so if every time you use a symbol from the other module, you need to type its namespace prefix, it makes you think twice about whether you really need to use it. Whereas if your entire codebase is one big single chunk of names, then there’s no friction for using any symbol anywhere, and you can get into spaghetti-land pretty quickly.

1 Like

Will do, thanks!

I’m totally with you for banning any using namespace in header files, but to clarify - you’re strictly against using it also in .cpp files? I thought of it as harmless and reducing clutter in those.

2 Likes

In my experience I’ve never seen any evidence of code being better without the prefixes.

I think that if you end up having a chunk of code which so absolutely stuffed with namespace prefixes that it’s becoming a problem, then it’s probably a hint that something else more fundamental needs fixing, rather than just trying to shorten the names in there.

What about the JUCE demos?

I was going to ask about why they use the juce namespace, but then saw that they don’t have a using namespace juce but rather implicitly use it. Is that a thing with PIP files?

There’s probably a lot of old code in the juce demos that needs a refresh, and cleaning up the namespaces is certainly something that probably needs to happen in a lot of them, to set a good example.

3 Likes

For the record, last year I took up the mantle of de-polluting our library codebase’s header files.

The actual library classes were all namespaced, thankfully. (All at the top level of one, single, library-wide namespace, though, which is only marginally less bad.)

The headers, however, were littered with using namespace std; and other transgressions which made using them an extremely fragile thing both internally and externally. Most frustratingly, they were prone to exhibiting confusing bugs anytime you dared to employ less-bad practices in code that used them.

(An issue exacerbated by the fact that the entire library’s codebase was written in an old-school C application style where each source file #includes only its corresponding same-named header, and all other #includes are placed there. I don’t know who’s to blame for ruining a generation of developers by making that nonsense sound like a smart idea, but hangin’ would be too good for 'em.)

So, we had lots of header files that all mutually (and circularly) #included each other up the wazoo, in addition to #includeing lots of other headers that they had absolutely no need for, simply because their implementations needed those symbols and somebody along the way had been abused into believing that better code organization came from making those dependencies as indirect and non-obvious as possible.

(Seriously — I swear this entire post isn’t intended as a rant about #include placement, and I will get tired of it eventually — I can’t even count how many headers I removed #include <iostream> from, and out of all of them only like two of their source files were even using iostream. When your #includes are in your headers, cutting-and-pasting the kitchen sink into each one becomes an easy bad habit. And while you’ll stick a new #include in there for a symbol you need in the source code, you’ll never remember to remove it when you change the source so it’s no longer necessary.)

Aaaanyway, my point is that this was motivated by a desire to get our source to compile with Clang, which was choking whenever one of our UnitTest+±driven tests included a header with audio classes in it. Unlike g++ which managed to work everything out, clang++ couldn’t resolve the UnitTest class’s ambiguity with juce::UnitTest in the presence of that default using namespace juce;

About halfway through the effort I did discover DONT_SET_USING_JUCE_NAMESPACE, but even sticking that into our unit tests was no help because it required our headers to be compatible with it, meaning the headers had to have juce:: prefixing in them. A lot of the headers, due to the aforementioned spaghetti of interdependencies.

Plus, at that point I was already committed enough that I decided actually fixing the entire issue was better than doing just enough to band-aid around it with some #defines. Even if my scorched-earth crusade I was on against all namespace pollution in the headers wasn’t strictly necessary, a real fix promised benefits well beyond the immediate problem of getting Clang working. (It’s like the climate-change conundrum: Imagine for a moment that somehow 97% of scientists are wrong about humanity’s impact on the global ecosystem and the necessary steps we need to take to correct for it. Why, if we listen to them, we could end up cleaning up the environment, reducing pollution, and making the world a cleaner, healthier, less toxic place to live “for no reason”!)

So, I went through and started systematically ripping out the using namespace std; from every header it appeared in. It took me the better part of an entire day, but that successful effort was also my third attempt — I’d made two prior runs at it and abandoned them both, mostly because of all the fun problems along the way. Things like:

  1. Turned out a surprising number of our .cpp files used unprefixed STL symbols, without a using namespace std; at the top of the file. Nor was it in the header file. They were implicitly picking it up from one of the many other header files it appeared in. (They don’t call it namespace pollution for nothing.) So, I would remove a namespace statement from one header, and three files in completely unrelated parts of the tree would suddenly explode with compile errors.
  2. In no small part because of ^, every time I cleaned up a header, the unresolved symbols would reliably cause a nerve-wracking and disheartening explosion of compiler errors from g++. If the spew was under 500 lines I was getting off easy. More often than not the first attempt would actually exceed my terminal’s 2000-line scrollback buffer, so I couldn’t even be sure what the total count was. I’d just have to slowly work through the deluge.
  3. Some of the bugs that cropped up were just weird. Like, we had one issue where a lot of math was off after the changes. Turned out, a class was using abs() with float arguments. std::abs() supports floats, but the C standard library’s abs() doesn’t: you have to use fabs(). While the namespace was polluted, abs() meant std::abs() and the math worked. After using namespace std; got removed, that abs() started to resolve to the C implementation thanks to some other header somewhere containing a #include <stdlib.h>.
  4. static_cast is not part of the STL. That’s not really a problem per se. I bring it up because trying to ingrain it into your own mind that you always write out the std:: in front of everything becomes that much more frustrating, every time you automatically type std::static_cast only to have it break the build again.
  5. One of the worst things about spaghetti #includes is, you edit a single header and suddenly half of your tree is recompiling. Seriously, friends don’t let friends code that way. It sucks bad enough when it’s application code, but if it’s a library and those are going to be PUBLIC headers it’s absolutely unforgivable. Embrace include what you use to put #include statements where they actually belong, and embrace the magic of the forward declaration over a full header #include wherever you can.
  6. We’d been patching bits of code inside and outside of the JUCE tree for years to work around things that ultimately proved to be namespace pollution issues. Beyond the UnitTest problems, we’d worked around issues with JUCE’s use of isfinite(), String clashing with a native symbol on MacOS, and probably more I’m not recalling. After cleaning up our global namespace, the only issue of that sort we still have is the fact that both FFmpeg and Ruby #define RSHIFT() as a macro in their headers, and worse they don’t even define it the same. (FFmpeg’s rounds, which is just evil when it’s called RSHIFT and not ROUNDING_RSHIFT.)

My point in all this, for the none of you who are still with me, is that as tedious as std:: and juce:: might seem when coding, it’s nothing compared to what you’ll have to go through later when you end up having to fix all the problems you create by taking shortcuts to avoid them. There are very good reasons why those shortcuts should never be used in headers under any circumstances, and really are better avoided as much as possible.

Plus, while I agree that writing C++ code does inevitably involve typing std:: quite a lot, like Jules said if you’re writing good JUCE code then you really shouldn’t be typing juce:: that often. Mostly it’s just the type names for your variable declarations that have to be prefixed. Most of the library calls will be methods of those objects, and those don’t have to be prefixed. Each object instance is effectively its own namespace prefix.

And you’ll type namespace prefixes even less often if you embrace auto, embrace ranged for loops so you don’t have to explicitly manage your iterators, and embrace std::make_shared and std::make_unique.

// Not only is this an inefficient way to create a shared pointer
// to a new object, in terms of the number of keypresses...
std::shared_ptr<juce::AudioFormatReader>
  our_source = std::shared_ptr<juce::AudioFormatReader>(new juce::AudioFormatReader(...));
// (Which is reason enough to prefer this equivalent form...)
auto our_source = std::make_shared<juce::AudioFormatReader>(...);

But in most implementations, the make_shared version is also slightly more efficient in terms of CPU cycles, performing just a single memory allocation. The first version requires a minimum of 2 separate allocations in current implementations, which can also make it less memory-efficient.

(And yes, I realize auto could also be used with the first version, to eliminate one of the two instances of std::shared_ptr<juce::AudioFormatReader>. I was exaggerating for effect.)

8 Likes

During my migration to Juce6 (finally) I’m going through this as well. Has anyone found a reliable way to (semi-) automate this? I see that clang in XCode most of the time is able to automatically guess the right type, but unfortunately I got lots of String converted to std::string instead of juce::String when I tried “Fix all Issues”. I have a feeling clang could do it all automatically and 100% correctly if only I would know the right way to call it.

Or is there any option in any IDE that has the option to spell out a certain namespace everywhere it is used? After all, before I turn off the namespace flag and the projects still build, the information is all there.

I’m scared of mistyping when I do it manually. I believe I have a couple of thousand spots in my large codebase. And repetive tasks tend to produce nasty bugs when they become boring.

Also… what to do about jassert(), DBG() and other JUCE macros? Now they stick out like nasty macros - which they are.

this looks promising, but how to use it?

I ended up doing it manually for my shared code and one plugin project. This took me about 4 hours and it was annoying work, but I found no easy reliable way to automate it. In my case most of the code I put inside methods didn’t need many fixes, but the biggest chunk of work was related to subclassing juce classes in my own namespace.

This leads to tons of juce:: in method declarations and definitions. I have many classes that subclass juce::ValueTree::Listener and juce::Component and both of these have many methods that pass around juce objects like juce::Graphics&, juce::Identifier or juce::ValueTree. All of these need the juce:: treatment. In that case scoped using directives cannot be used and auto also isn’t available. The absolute worst part was my own LookAndFeel which lives in my own namespace and overrides many methods of the JUCE LookAndFeel and all of these pass juce:: objects.
Unless I’m overlooking something here…?

What is kind of scary is that this makes subclassing JUCE classes harder as it’s no longer possible to copy the method declarations from the JUCE code inside the namespace juce {} scope and therefore doesn’t need juce::. So now every time I subclass/override a new method I’ll have to add some juce:: :confused: .

Example: subclassing ValueTree::Listener now becomes

void valueTreePropertyChanged (juce::ValueTree& vt, const juce::Identifier& propID) override;
void valueTreeChildAdded (juce::ValueTree& parentTree, juce::ValueTree& child) override;
void valueTreeChildRemoved (juce::ValueTree& parentTree, juce::ValueTree& child, int oldIndex) override;
void valueTreeChildOrderChanged (juce::ValueTree& parentTree, int oldIndex, int newIndex) override;
void valueTreeParentChanged (juce::ValueTree& treeWhoseParentHasChanged) override;

Maybe JUCE could help by adding extra juce:: to commonly overridden methods… especially abstract ones that have to be overridden.

1 Like

I’m no expert on this, but can’t you also do something like:

using ValueTree = juce::ValueTree;
void valueTreePropertyChanged (ValueTree& vt, const juce::Identifier& propID) override;
void valueTreeChildAdded (ValueTree& parentTree, ValueTree& child) override;
void valueTreeChildRemoved (ValueTree& parentTree, ValueTree& child, int oldIndex) override;
void valueTreeChildOrderChanged (ValueTree& parentTree, int oldIndex, int newIndex) override;
void valueTreeParentChanged (ValueTree& treeWhoseParentHasChanged) override;

it is a big chunk to bite off, but I encourage everyone to recognize that the pain is from having done things, um, less than preferred (ie. misusing namespaces), and that seeking things to maintain that is the wrong direction. we need to let go of habits that don’t serve us, and embrace how C++ continues to improve, through both the language constructs, and the core guidelines.

This guideline refers to the standard library, but I think it holds true for namespaces in general:

Of course you can do that, but then you pollute your namespace again, especially if you do this in a header file. Then the whole exercise becomes a bit moot as nothing is gained. My goal is clean namespaces and no using namespace … anywhere.

I read this a while ago so I might not remember everything, but I think a big difference to JUCE is that the standard library discourages creating subclasses of its objects and JUCE encourages/forces creating subclasses of JUCE classes like juce::Component.

I’m basically looking for a best practice how to subclass an object living in a different namespace and I don’t remember the guideline having advice for this case.

That is a great question, and I would be interested in the answer as well. :slight_smile:

juce:: is part of the name of its classes, structs, functions, etc. You have to write it in your code! It can be omitted for convenience only in its library itself. How else would you distinguish between a common identifier like Value?

I really don’t get the discussion and I can’t believe I feel the need to respond to this topic! Namespaces are around for some days now and a pretty convenient way of forcing a naming policy on shared code. But people tent to think it’s something optional. (JUCE itself did a bad job by having turned them off in the first place.)

The worst example of polluting the common namespace is Windows.h.
The lack of distinction of such code to the projects code makes me referencing it consequently with ::! Just as a lead for maintainers.

Software projects get really complex these days and usually a lot of third party and common code is used, so there is no way around namespaces. Just because JUCE is all-embracing (and therefor most likely avoiding other third party code) seems to mean to people there is no need for distinction.

I am still hoping JUCEs macro orgy gets cleaned up some day, this is at the same level of misconception as not using namespaces and certainly not the correct way of configuring C++ code. And BTW nobody ever complained about all macros starting with JUCE_? Why do you think this is?

2 Likes

Instead of adding more bad examples, maybe you could have explained to us how you would create a subclass of juce::LookAndFeel in your own namespace with 30-40 method overrides.

How often are doing this? And you probably not overriding all at once, do you? For the rest I am sure there is some intelligent way of find and replace, or adding the namespace manually. Thats a 3 min job, if at all. Probably took longer to ask the question.

A solution I’ve found is to create some small scope namespace for your own classes, and import the commonly used types into it.

For example:

namespace MyCompany::GUI
{
    using juce::Component;
    using juce::ValueTree;
    using juce::String;
    //etc.
}

That way you be can somewhat confident about the types you’re importing, as you’re managing your own namespace and know if there could be any collisions there with those specific types, without importing the entire juce namespace globally.

2 Likes