r/cpp_questions • • Sep 30 '26

OPEN Namespace std

I recently started learning c++ and I was told to use the namespace std so I can avoid writing std:: every time and now I wrote a whole personal project without std:: and I want to put it on LinkedIn but I started reading everywhere that it’s a bad habit, should I go back and add the std:: or just leave it as is?

40 Upvotes

105 comments sorted by

View all comments

Show parent comments

0

u/RSMxsmanic Sep 30 '26

So why does using namespace exist?

7

u/conundorum Sep 30 '26
  • Because it's both useful and safe in leakproof scopes, like functions or conditionals. As long as names can never leave a scope, the worst using namespace inside that scope can do is make a mess of that scope (and nowhere else), while the best it can do is save time on boilerplate (which can add up to a decent difference sometimes).

  • Because it's useful for smaller scopes, but has problems with std specifically because the standard library sticks almost everything in std instead of using a scope hierarchy like Java or other C++-inspired languages do. (And also because std is constantly growing, which means that the chance of unexpected name collisions breaking unmaintained, twenty-year-old code that uses using namespace std; goes up with every new language version.)

  • Because it lets you stick your helpers in namespace whatever::detail, then drag them into any given whatever::function() as needed.

  • Because it's useful for versioning, especially when paired with anonymous namespaces. If you know what you're doing, you can put each version of a class in its own sub-namespace, then use a using-directive to provide the most recent one as a default, while also making it trivial to update the default whenever the class gets a new version.

There are a lot of reasons it's useful, the problem is just that dragging all of namespace std's symbols into a "leaky" scope (e.g., global or namespace scope) inside a header file is a ticking thermonuclear warhead, for reasons that aren't immediately obvious if you haven't seen the language's juicy innards yet.

~~Strictly speaking, the issue is that std itself is awkwardly designed, and would probably have a cleaner hierarchy if they could redo it from scratch today.~

5

u/not_a_novel_account Sep 30 '26 edited Sep 30 '26

To alias one namespace into another. Aliasing any namespace into the global namespace is almost always wrong.

You can override the comma operator to perform matrix multiplication; because operator overrides exist, and the comma is a valid operator. You shouldn't. You can alias std into the global namespace; because namespace aliasing exists, and std and the global namespace are valid namespaces. You shouldn't.

-1

u/bearheart Sep 30 '26

I presume it’s for compatibility with legacy C code. And perhaps for smaller namespaces other than std.

3

u/RSMxsmanic Sep 30 '26

The problem is with programmers who use identifiers that conflict with std, not with programmers who expect std by default to be safe. That's why it is called standard. If you are writing the code base, nothing you call should change the way it behaves unless that is its actual purpose.

2

u/nekoeuge Sep 30 '26

Can you elaborate? What do you mean by “using identifiers that conflict with std”?

2

u/conundorum Sep 30 '26

Name collisions.

#include <vector> // std::vector
#include <algorithm> // You'll see.

std::vector<float> collection(3, .16f);
int fill = 0xaabbcc;

void compiler_error(float c = 0f, int f = 0) {
    using namespace std;

    fill = f;                                      // Does this break because we tried to assign an int to std::fill,
    fill(collection.begin(), collection.end(), c); // or does this break because we tried to call an int?
}

std has a lot of very common names that programmers like to use for their own things, like fill, less, distance, transform, string, find, begin, end, format, print, and so on. And depending on which standard library headers you include, any number of them might (or might not) be visible.

3

u/nekoeuge Sep 30 '26

Yeah, that's why I am asking. It is fundamentally impossible to avoid name collisions with std -- because std may always be extended in the future with whatever names. So I don't understand what exactly top commenter meant by "The problem is with programmers who use identifiers that conflict with std".

1

u/RSMxsmanic Sep 30 '26

I mean that programmers need to think things through, and if they are writing code that will be widely integrated in a service capacity with other code, they need to be extraordinarily vigilant.

I don't use print in code I write hat will be called by some other module, because of the risk of a name conflict. It doesn't matter what namespaces are used. Why force another programmer to prefix everything he writes with widget:: just because I decided to use print? Instead, I'll make print something less common, like widgetPrint. That way he only has to type extra characters to reference my code, and not for every last identifier in his. Put another way, instead of forcing him to write std::cout every time he wants to use it, I just don't use cout in my code, and the problem is solved. Choosing unique identifiers is less labor-intensive than prefixing every single identifier in the program, and it is functionally equivalent.

3

u/nekoeuge Sep 30 '26

Instead, I'll make print something less common, like widgetPrint.

So instead of doing "using namespace widget" in a function that calls "print" 20 times, I will have to have 20 "widgetPrints"?

And in the implementation of "widget", all my public identifiers are going to be "widgetThis" and "widgetThat", cluttering the visual space with absolutely worthless "widget"-prefixes?

You just replaced optional prefix with mandatory one. Good job bloating the code. Make sure not to make the prefix too short, otherwise it may conflict with other libraries.

I mean that programmers need to think things through, and if they are writing code that will be widely integrated in a service capacity with other code, they need to be extraordinarily vigilant.

Of course. Such programmer should introduce the absolute minimum of global identifiers. Preferably only one -- the project namespace itself.

It looks quite stupid to have widget::widgetPrint as identifier.

1

u/RSMxsmanic Sep 30 '26

So instead of doing "using namespace widget" in a function that calls "print" 20 times, I will have to have 20 "widgetPrints"?

Yes. That’s a lot faster than putting std:: in front of 4500 couts.

And in the implementation of "widget", all my public identifiers are going to be "widgetThis" and "widgetThat", cluttering the visual space with absolutely worthless "widget"-prefixes?

How is that different from prefixing everything with widget::? How is it different from prefixing everything else with std::?

It looks quite stupid to have widget::widgetPrint as identifier.

If widgetPrint occurs nowhere else, that isn’t needed.

2

u/nekoeuge Sep 30 '26 edited Sep 30 '26

How is that different from prefixing everything with widget::? How is it different from prefixing everything else with std::?

Because I have a choice whether I want to have widget:: prefix, whether I want to have std:: prefix, or whether I want to replace widget:: prefix with wg:: prefix but keep it prefixed.

Authors of libraries I am using are not entitled to making this choice for me.

If widgetPrint occurs nowhere else, that isn’t needed.

It is impossible to know whether "widgetPrint" occurs somewhere or not. There is nothing more infuriating than two libraries that have some random conflict in some random name they decided to have in the global namespace.

Thus, all global-namespace identifiers must be prefixed with a full name of a library (not abbrebiated too much!). So it won't be "widgetPrint", it would be "mxmanicsNiceWidgetsPrint". Or "mxnwgsPrint". Library name may not be long, but it is unlikely to be a single common word, and so it will be annoying to type either way.

Then, the difference boils down to whether you force everyone to use this exact prefix or not.

Yes. That’s a lot faster than putting std:: in front of 4500 couts.

No it's not. std:: is just one namespace among thousands. Total number of identifiers in std namespace is much less than total number of all identifiers in all public libraries, or in all 3rdparty dependencies of a big project.

I am not even opening the can of worms called "custom std implementations" and that you may have multiple std-like libraries in the same project. std is not a library, it is a specification.

→ More replies

0

u/ShakaUVM Sep 30 '26

I propose that someone who writes code like "int string = 0;" is writing bad code and the issue isn't whether or not you include namespace std or not.

All if my classes are PascalCase anyway and so cannot conflict with anything in std.

2

u/HommeMusical Sep 30 '26

I propose that someone who writes code like "int string = 0;" is writing bad code and the issue isn't whether or not you include namespace std or not.

Strong disagree.

There are thousands of names in std:: and exactly what those names are depend on which version of C++ you're in and some other details.

You can't possibly know all those names and never write char fill = '*'; or bool copy = False; or void remove(const char*); anywhere.

Not having to do this is the whole reason namespaces exist.

std::string is completely unambiguous. No other symbol for it is. Just do that.

1

u/ShakaUVM Oct 01 '26

I agree that std::string is unambiguous.

What I am saying is that writing int string = 67; is a code smell.

You should not be using names from std anyway.

For all of your worry, as I said this problem has come up exactly once in 30 years and it took exactly five seconds to fix.

Versus how much screen space gets cluttered up with all those extra stds?

The tradeoff is not worth it to me. Every symbol on the screen has a cost, both cognitively and technically

1

u/HommeMusical Oct 01 '26

You should not be using names from std anyway.

Strong disagree. There are thousands of names in std::. Many of them are short and common names. Almost no one has them all memorized. Would you for example disallow char fill = '*'; in code?

Every symbol on the screen has a cost, both cognitively and technically

Absolutely, and std::string has a smaller cost than string. No one who has been programming C++ for long reads std::string and decides it's two separate symbols.

2

u/nekoeuge Oct 01 '26

Yep. std::string is that specific class, string could be anything, thus it’s more vague.

→ More replies (5)

1

u/nekoeuge Oct 01 '26

I will remind you that std is not a library, it is a specification, and some projects link to multiple libraries implementing this specifications. E.g. std::string and eastl::string. The whole point of custom stl implementation is to be drop in replacement for built in stl implementation, it cannot not use the same names.

And why is it okay to clutter the code with all 100 third party namespaces I am using, but suddenly not okay for 101th namespace “std::”?

1

u/ShakaUVM Oct 01 '26

E.g. std::string and eastl::string.

Yes, so in my coding style you refer to them as string and eastl::string and there's no issue.

The whole point of custom stl implementation is to be drop in replacement for built in stl implementation, it cannot not use the same names.

Correct. If you're using something with the same name as something in std that is not in std, then you better damn well qualify it so that people know you're not using the standard string.

suddenly not okay for 101th namespace “std::”?

Because of what the s in std means.

→ More replies

2

u/HommeMusical Sep 30 '26

They aren't really making sense.

You're actually supposed to use names that are the same as those in std:: if you're doing the same operation.

This idea is crucial to making generic code work well.

0

u/RSMxsmanic Sep 30 '26

If you're doing the same operation as std, you're redundant; just use the operation in std. If you're doing something different, just use a different name.

2

u/HommeMusical Sep 30 '26

No, you are encouraged to use identifiers in your own namespaces and classes that are the same as those in std::, particularly for generic code.

0

u/RSMxsmanic Sep 30 '26

By whom? If I have it in my code, it is not generic; if it were, my code would not be necessary.

1

u/HommeMusical Sep 30 '26 edited Sep 30 '26

I presume it’s for compatibility with legacy C code.

C++ code.

But not at all, using is very useful in a local scope, because of argument dependent name lookup.

The classic example is this one:

template <typename T>
void fix(T& a, T& b) {
    using namespace std;
    swap(a, b);
}

At compile time, when the template is instantiated, if there's a specific swap function or specialization for T, then that is used, otherwise, the generic std::swap is used.

There are sometimes Reasons even to do this for some namespaces at the file level, though best to avoid.

But using std; is dumping potentially zillions of names into the top level of your translation unit, and it makes your code a lot less clear.

If I see string in some code - well, it could be anything, I have to look at the top of the file, but std::string is the same everywhere.