What Are the Reasons That Extending the Std Namespace Is Considered Undefined Behavior

What are the reasons that extending the std namespace is considered undefined behavior?

Here are a few reasons:

  1. Even if names in headers have to be uglified to avoid interactions with macros, this requirement does not exist for name in the source files actually implementing the code. If an implementation does use ::std::foo(int) as part of its implementation it would be a violation of the one definition rule.
  2. The standard is expected to grow. If names could be added to namespace std any name added to the standard C++ library would be a likely breaking change. To some extent this is already true in the sense that any such name could be a macro but it is considered acceptable to break those.
  3. There is actually no need to add names to namespace std: they can be added to arbitrary other namespace, i.e., even if the motivations given above are not particular strong, the restriction isn't considered to matter in any form. ...and if there is a reason to add a name to namespace std, it clearly does affect the behavior.

C++ When is it OK to extend the `std` namespace?

The only case where it is OK to add a definition into the std namespace is specialization of a template that already exists in the namespace and to explicitly instantiate a template. However, only if they depend on a user defined type.

[namespace.std] (standard draft):

  1. The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified. A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.

  2. The behavior of a C++ program is undefined if it declares

    (2.1) an explicit specialization of any member function of a standard library class template, or

    (2.2) an explicit specialization of any member function template of a standard library class or class template, or

    (2.3) an explicit or partial specialization of any member class template of a standard library class or class template.

    A program may explicitly instantiate a template defined in the standard library only if the declaration depends on the name of a user-defined type and the instantiation meets the standard library requirements for the original template.


As an example of standard templates that are explicitly designed to be extended for user defined types: std::hash and std::iterator_traits.

Is using nested std and posix namespaces undefined?

It's indeed a somewhat obscure rule of English. You see that the rules talk about a namespace within namespace std. Why aren't we talking about "a namespace std" or "the namespace std"? It's because std is the (unique) name of that namespace. Compare "a president", "the president", "president Trump".

So yes, namespace std uniquely refers to that top-level namespace.

Why is using namespace std; considered bad practice?

Consider two libraries called Foo and Bar:

using namespace foo;
using namespace bar;

Everything works fine, and you can call Blah() from Foo and Quux() from Bar without problems. But one day you upgrade to a new version of Foo 2.0, which now offers a function called Quux(). Now you've got a conflict: Both Foo 2.0 and Bar import Quux() into your global namespace. This is going to take some effort to fix, especially if the function parameters happen to match.

If you had used foo::Blah() and bar::Quux(), then the introduction of foo::Quux() would have been a non-event.

Adding types to the std namespace

No ... part of the point of a namespace is to prevent name collisions on upgrade.

If you add things to the std namespace, then your code might break with the next release of the library if they decide to add something with the same name.

Extending namespace std to implement make_unique when using C++11

No, this is forbidden—even though, via

#define make_unique ? ? ?

a conforming C++11 program can be quite sure that the library never mentions the name (outside of a stringization) and would thus be unable to detect the extension.



Related Topics



Leave a reply



Submit