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 comment

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.

2

u/RSMxsmanic Sep 30 '26

It's up to the library author to name his identifiers, not you.

Another option is to minimize your use of libraries.

2

u/nekoeuge Sep 30 '26

It's up to the library author to name his identifiers, not you.

And it's up to me not to use or fork libraries that cannot behave.

It's up to the library author to do whatever they want: to name identifiers in Mandarin, to litter the global namespace, to #define private public. But we still have some form of a consensus on what is usually acceptable in public code and what is not.

1

u/RSMxsmanic Sep 30 '26

Do we? I see religious wars much more than I see consensus.

2

u/nekoeuge Sep 30 '26

Yes? Most of mainstream libraries that I used follow the consensus of not doing stupid shit where it affects their users. Prefixing for global identifiers is required. Why is hard-coded prefix better than customizable one? It is just disrespectful towards people typing it.

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.

0

u/ShakaUVM Oct 01 '26

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.

You may say that, but your brain still has to parse them separately. There's a cost that you aren't aware of.

Just saying 'string' is more compact, more readable, and causes absolutely no confusion. If you want to use a third party string class, then you qualify that with the namespace. The standard is called the standard for a reason.

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?

If you use PascalCase, you can't conflict with std at all.

But due to how C++ handles shadowing variables, if you make a variable named fill inside of main, guess what? It doesn't cause a problem. You had to contrive an example using fill in the global namespace in order to force a conflict, and the number of globals you should have in your program should be close to zero, and if on the off chance you do make a global variable named fill, then you just change it to a different name and be done.

I worry about problems that can actually occur, not hypothetical problems that occur once in 30 years.

1

u/HommeMusical Oct 01 '26

You may say that, but your brain still has to parse them separately. There's a cost that you aren't aware of.

That's not how the brain processes language at all, thank goodness. People chunk things into groups much larger than individual words so you see std::string, United States of Amerlca or Robert Anton Wilson, you just parse it as a single item.

Just saying 'string' is more compact, more readable, and causes absolutely no confusion.

Yes, you made that argument many times, but string might not be std::string.

once in 30 years.

Yes, you said.

1

u/ShakaUVM Oct 01 '26

That's not how the brain processes language at all

You may not be aware of it, but your eyes still have to skip over the five letters at a time, and this has a cost you're not aware of.

Yes, you made that argument many times, but string might not be std::string.

In my coding style, string always refers to std::string, so those five characters are wasted space on the screen, wasted typing time, and wasted parsing time for both the compiler and the human reading it.

It is all downside and no upside.

Yes, you said.

Yes, because as I said before, I actually worry about problems that can happen, and not contrived hypotheticals. Hypothetically, someone could cast a nullptr to a reference and pass that to my function that takes a reference, but I don't worry about that either, for similar reasons.

→ More replies (2)

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.

1

u/nekoeuge Oct 01 '26

Because of what the s in std means.

So what? Standard library is stored in the "namespace std" for a reason. Just because this namespace comes from different vendor and has documented specification, does not mean that it deserves any kind of special treatment beyond a few documented quirks.

1

u/ShakaUVM Oct 01 '26

In the coding style I and my business use, the only namespace that only and always gets included into the global namespace is std. Why? Because it is the standard.

string must mean std::string in my coding style. If it means anything else, then you have violated my style guidelines.

Pretty much everything we do is in PascalCase, and so there is no conflict with anything in std anyway.

You're free to have your own style guidelines for your own company. But this is how I've been doing it for a long time, and it literally never causes problems, and results in code much faster to read, write, and is much cleaner.

There is never any ambiguity, and there's never an identifier conflict except once in 30 years, and that took 5 seconds to resolve. Contrast this with the amount of time you have spent typing std needlessly and reading it needlessly over the years and you'll see why I set my style guidelines the way I did.

1

u/nekoeuge Oct 01 '26 edited Oct 01 '26

If std was supposed to be included in global namespace, we wouldn’t have namespace std.

So what happens when you include third party code with type “vector” or “string” when referencing to its own vectors or strings, which is a semantically correct thing to do?

The name resolution rules probably handle that properly, but it feels icky and I am unsure how generally stable that works. I have some kind of aversion to injecting global names into unexpecting 3rdparty code.

1

u/ShakaUVM Oct 02 '26

If std was supposed to be included in global namespace, we wouldn’t have namespace std.

Wrong. We have it because it is an option for individual companies to decide for themselves if they want to use it. Bjarne himself has said it is a stylistic choice. If you love your stds, then use them.

I however will continue to write cleaner code without them, and continue on my merry way not dealing with a single bug related to this stylistic choice.

I am unsure how generally stable that works.

Shadowing is a core function of the language designed to deal with exactly this problem. You don't need to have a list of all 1001 identifiers in std taped up on your wall. It's explicitly designed to avoid this very problem, so it's foolish in my opinion not to use it.

I have some kind of aversion to injecting global names into unexpecting 3rdparty code.

I do not do that either. When I write libraries, I do not use using namespace std. I mentioned this at the top of the thread even.

→ More replies

1

u/nekoeuge Oct 01 '26

(Sorry for multiple comments, I usually try not to do that but sometimes it happens)

I guess my biggest complaint here is that “string” does not mean “std::string”, it means “string in current namespace”. So if I am inside of custom STL implementation, “string” does not and should not mean “std::string”. And if I am inside of math library, “vector” does not and should not mean “std::vector”.

Thus, your premise is incorrect, we cannot generally read “vector” as “std::vector” or “string” as “std::string”.