Namespaces
Variants
Views
Actions

Talk:cpp/language/namespace

From cppreference.com

Contents

[edit] Confusion regarding global namespace injection

I have had my edit reverted by D41D8CD98F regarding the "injection" of names into global namespaces. This is the revert: https://en.cppreference.com/mwiki/index.php?title=cpp/language/namespace&diff=prev&oldid=122329.

I went ahead and reverted the revert.

Nothing gets injected into global namespaces. This does not occur under any circumstance, unless you explicitly bring a namespace into the global namespace. Yet Cubbi originally added this language and examples to that effect, and D41D8CD98F also insists that's the case. It really is not -- here is an example, taken verbatim from this wiki page but edited to add static_assert to test things.

https://gist.github.com/cculianu/14765a93cdaf9a7c5729a192fd5b6b20

You're misinterpreting what it means to inject the names into the nearest common ancestor namespace, see https://abseil.io/tips/153 for details --Ybab321 (talk) 02:43, 8 September 2020 (PDT)

Hi Ybab321. Thanks for responding. I do not believe the example given from the abseil site is correct or even relevant. Nothing is injected into the global namespace even in their example! the global namespace has a precise technical definition.

This is their example with code added to test the hypothesis they present:

namespace testing {
    constexpr int foo = 123;
    struct Sequence {};
    struct WallTimer {};
}
 
namespace totw {
namespace example {
 
void TEST(int MyTest, int UsesUsingDirectives) {
  using namespace ::testing;
  Sequence seq;  // ::testing::Sequence
  WallTimer timer;  // ::testing::WallTime
  ::Sequence seq2; // <--- compile failure *Not* injected to global namespace even here!
}
}  // namespace example
}  // namespace totw
 
static_assert(foo == 123); // compile failure, name foo not known here
static_assert(::foo == 123); // compile failure, name foo not still not known here

--Cculianu (talk) 13:13, 8 September 2020 (UTC)

the section of this page that talks about using-directives starts with the words "From the point of view of unqualified name lookup", thus examples that use "::Sequence" and "::foo" are not applicable. It also says "until the end of the scope in which it appears", so your last "foo == 12" static assert is not applicable either. We could add "for unqualified name lookup" to the note as well, but it would be 100% incorrect to change the example and the note to say "into D", "into C" or "given namespace", since those are not the effects of using-directive - the abseil page already gets into the details of this common misconception, and the wording on this page attempts to do the same. Cubbi (talk) 08:35, 8 September 2020 (PDT)

Ok, then please do not use the term "global namespace". The term "global namespace" has a precise definition. Nothing is being put into the global namespace. --Cculianu (talk) 13:13, 8 September 2020 (UTC)


From the draft standard here: https://eel.is/c++draft/basic.scope.namespace#4

The outermost declarative region of a translation unit is also a namespace, called the global namespace. A name declared in the global namespace has global namespace scope (also called global scope). The potential scope of such a name begins at its point of declaration ([basic.scope.pdecl]) and ends at the end of the translation unit that is its declarative region. A name with global namespace scope is said to be a global name.

As you can see the term "global namespace" has a precise technical definition. No names are being injected into this namespace in any of the examples that you reverted back yet again.

What you really mean is that the name lookup in that scope is being affected. As well as names literally being injected into the namespace transifively. That's it. Cculianu (talk) 09:58, 8 September 2020 (PDT)

the term "global namespace" is used here in that technical meaning. For the purpose of unqualified name lookup, the names appear as if they were declared in the global namespace. That's literally the definition of using-directive in namespace.udir/2 --Cubbi (talk) 10:48, 8 September 2020 (PDT)
I came here looking for the precise terminology for the global namespace (I had been incorrectly saying "root namespace"). Right now the page is not clear about defining the global namespace and global scope. It really should (and there should be a redirect from the page global namespace (and probably global scope, root namespace, and root scope) to that definition. The standard defines them like this: [1]:
"There is a global namespace with no declaration; see [basic.scope.namespace]. The global namespace belongs to the global scope; it is not an unnamed namespace ([namespace.unnamed])."
I'm inclined to put a definition like this in the intro paragraphs before the "Syntax" section since they are namespacey things that basically have no syntax. Sound reasonable? BenFrantzDale (talk) 04:37, 20 October 2023 (PDT)
Sounds good to me --Ybab321 (talk) 06:05, 20 October 2023 (PDT)

[edit] Strange wording for syntax 5

"the nearest enclosing namespace which contains (directly or indirectly) both the using-directive and the namespace ns_name." THis wording makes it sound like this should compile: http://ideone.com/4kmcHy I think it should be clarified. LB(T|C) 19:17, 27 March 2014 (PDT)

it's explained later in the using-directive's paragraph, but I'll add to the summary too (that it's only in effect until the scope ends) --Cubbi (talk) 19:32, 27 March 2014 (PDT)

[edit] Mistake in Syntax 6

"(6) using-declaration: makes the symbol name from the namespace ns_name accessible for unqualified lookup as if declared in the same namespace as where this using-declaration appears." Shouldn't this be "... in the same declarative region ..."? If it was the same namespace, a using-declaration used in a member function would not shadow other member functions. --Mkl (talk) 02:58, 13 October 2015 (PDT)

it does say "declarative region" later on the page, where it discusses the actual semantics, but it may be too standardesey for the summary. Perhaps "scope or namespace" would be a better intro. --Cubbi (talk) 06:20, 13 October 2015 (PDT)

[edit] What is an "original-namespace-definition"?

This is a very important concept for namespaces, as it's tied into `inline namespace` and so forth. This page mentions it several times, but never actually explains what it is.

the page currently says, when introducing namespace definition, that the identifier in it may be "a previously unused identifier, in which case this is original-namespace-definition". I think that the dashes can be dropped from all its uses here, "original namespace definition" is a fairly descriptive English. --Cubbi (talk) 14:39, 10 July 2016 (PDT)

[edit] Adding the unnamed namespace code example of what it does is useful

I added example of what unnamed namespace means in the code, and what is described with words right now on the page:

> This definition is treated as a definition of a namespace with unique name and a using-directive in the current scope that nominates this unnamed namespace.

This was reverted with the note, that it does not reflect the internal linkage change. I strongly believe it's beneficial to add this to the unnamed namespaces section again, because:

1. The prose, that example was presenting also didn't mention the linkage change. The linkage change is mentioned in a different place (couple of lines further).

2. The code example is also present in the C++ draft http://eel.is/c++draft/basic.namespace#namespace.unnamed-1 and it is correct to say so.

3. It's better to show actual code by example rather than describe the code.

The practical reason for pasting that in, is that when trying to figure out how it happens, that unqualified name lookup also considers unnamed namespace is much easier, when there is a code to be considered.

[edit] Missing description of how qualified name lookup is affected by using directive

Some kind of reference to the https://en.cppreference.com/w/cpp/language/qualified_lookup should be added, to make description of the using directive complete.

[edit] Inline-namespace library versioning example needed

The inline namespaces section currently bows out with this tantalizing claim:

Note: the rule about specializations allows library versioning: different implementations of a library template may be defined in different inline namespaces, while still allowing the user to extend the parent namespace with an explicit specialization of the primary template.

...which is then never returned to or expanded on. Maybe I'm just slow, but I'm having difficulty envisioning exactly what's being described there and how it would be put into practice. Might someone be able to supply an expanded explanation, and/or some example code?

I'll even take a link to explanatory reading material elsewhere! (And perhaps come back and incorporate some of it once I've gotten up to speed.) -- FeRDNYC (talk) 03:43, 24 February 2022 (PST)

I suppose we can copy the example from http://wg21.link/n2535 --Cubbi (talk) 10:40, 24 February 2022 (PST)