C++ supports two permutations on regular namespaces that are worth at least knowing about. We won’t build on these, so consider this lesson optional for now.
Unnamed (anonymous) namespaces
An unnamed namespace (also called an anonymous namespace) is a namespace that is defined without a name, like so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <iostream> namespace // unnamed namespace { void doSomething() // can only be accessed in this file { std::cout << "v1\n"; } } int main() { doSomething(); // we can call doSomething() without a namespace prefix return 0; } |
This prints:
v1
All content declared in an unnamed namespace
is treated as if it is part of the parent namespace. So even though function doSomething
is defined in the unnamed namespace
, the function itself is accessible from the parent namespace (which in this case is the global namespace
), which is why we can call doSomething
from main
without any qualifiers.
This might make unnamed namespaces
seem useless. But the other effect of unnamed namespaces
is that all identifiers inside an unnamed namespace
are treated as if they had internal linkage
, which means that the content of an unnamed namespace
can’t be seen outside of the file in which the unnamed namespace
is defined.
For functions, this is effectively the same as defining all functions in the unnamed namespace
as static functions
. The following program is effectively identical to the one above:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> static void doSomething() // can only be accessed in this file { std::cout << "v1\n"; } int main() { doSomething(); // we can call doSomething() without a namespace prefix return 0; } |
Unnamed namespaces
are typically used when you have a lot of content that you want to ensure stays local to a given file, as it’s easier to cluster such content in an unnamed namespace
than individually mark all declarations as static
. Unnamed namespaces
will also keep user-defined types
(something we’ll discuss in a later lesson) local to the file, something for which there is no alternative equivalent mechanism to do.
Inline namespaces
Now consider the following program:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> void doSomething() { std::cout << "v1\n"; } int main() { doSomething(); return 0; } |
This prints:
v1
Pretty straightforward, right?
But let’s say you’re not happy with doSomething
, and you want to improve it in some way that changes how it behaves. But if you do this, you risk breaking existing programs using the older version. How do you handle this?
One way would be to create a new version of the function with a different name. But over the course of many changes, you could end up with a whole set of almost-identically named functions (doSomething
, doSomething_v2
, doSomething_v3
, etc…).
An alternative is to use an inline namespace. An inline namespace is a namespace that is typically used to version content. Much like an unnamed namespace
, anything declared inside an inline namespace
is considered part of the parent namespace. However, inline namespaces
don’t give everything internal linkage
.
To define an inline namespace, we use the inline
keyword:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <iostream> inline namespace v1 // declare an inline namespace named v1 { void doSomething() { std::cout << "v1\n"; } } namespace v2 // declare a normal namespace named v2 { void doSomething() { std::cout << "v2\n"; } } int main() { v1::doSomething(); // calls the v1 version of doSomething() v2::doSomething(); // calls the v2 version of doSomething() doSomething(); // calls the inline version of doSomething() (which is v1) return 0; } |
This prints:
v1 v2 v1
In the above example, callers to doSomething
will get the v1 (the inline version) of doSomething
. Callers who want to use the newer version can explicitly call v2::dosomething()
. This preserves the function of existing programs while allowing newer programs to take advantage of newer/better variations.
Alternatively, if you want to push the newer version:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
#include <iostream> namespace v1 // declare a normal namespace named v1 { void doSomething() { std::cout << "v1\n"; } } inline namespace v2 // declare an inline namespace named v2 { void doSomething() { std::cout << "v2\n"; } } int main() { v1::doSomething(); // calls the v1 version of doSomething() v2::doSomething(); // calls the v2 version of doSomething() doSomething(); // calls the inline version of doSomething() (which is v2) return 0; } |
This prints:
v1 v2 v2
In this example, all callers to doSomething
will get the v2 version by default (the newer and better version). Users who still want the older version of doSomething
can explicitly call v1::doSomething()
to access the old behavior. This means existing programs who want the v1 version will need to globally replace doSomething
with v1::doSomething
, but this typically won’t be problematic if the functions are well named.
![]() |
![]() |
![]() |
doesn't inline namespaces basically returned the issue with namespace collision ?
since the functions inside of it are now part of the parent scope. any function definition with the same name will now be in conflict with the inline function.
what if we had something like
so that there is a dosomething in global namespace as well as inline one. Which one takes priority?
Your global namespace `dosomething()` is all lower case while the namespaced ones are camel case `doSomething()`
dosomething
doSomething
This program should return v1v2 but it's returning 11. Why is it so!?
`_v1` and `_v2` return `void`. Their return value can't be printed, because they don't have a return value.
You're sending the functions themselves to `std::cout`. `std::cout` converts them to `bool`, which are `true`, so you're getting "11" (true true).
Oh yeah I get it now. Thank you.
Instead of using inline why just not make a second namespace v2 like
Because then you have to access `doSomething` as `v2::doSomething()`. When you use `inline namespace`, you'll do so in another `namespace`, so you'd end up with `something::v2::doSomething()`. The user shouldn't care about the version.
Hi, thank you for the lesson! Maybe someone else made this mistake, so I thought I would comment it.
In the last two examples there is a inline namespace and a "normal" namespace. I incorrectly thought the "normal" namespace was an unnamed namespace.
Because of this I was confused why doSomething(); would call the inline namespace version instead of what I thought was a unnamed namespace, which also, in this case shared the same parent namespace, the global namespace.
But in the examples, the "normal" namespaces are not a part of the global namespace. Hence what ended up being printed.
Hope this helped.
Hi,
1) "For functions, this is effectively the same as defining all functions in the unnamed namespace as static functions."
In the following code, we have the unnamed namespace BUT the function is not 'static'! While the sentence above says functions in the the unnamed namespace should be static! Also, as you said, "all identifiers inside an unnamed namespace are treated as if they had internal linkage", then why should we add 'static' keyword for functions inside the unnamed namespace when they are already have internal linkage in the code below?!
> In the following code, we have the unnamed namespace BUT the function is not 'static'
It's not supposed to be. Functions inside an unnamed namespace don't need to be `static`, because they already have internal linkage.
Thank you. About the following?
"One way would be to create a new version of the function with a different name."
Can't we use function overriding, instead of naming functions with almost-identical identifiers?
Do you mean function overloading? The function's parameters didn't change, so we can't overload it.
Yes I did.
Very good point! I got it. Thanks.
In the last example,why can't we use unnamed namespace instead of inline namespace.And I also don't get the difference between inline namespace and unnamed namespace.
An unnamed namespace gives internal linkage to its inner declared identifiers.
You likely want to preserve external linkage to ease versioning refactor involving multiple files.
Inline namespace can provide external linkage, that is can be used in other files. please give an example for it.
I'm not the author but as far as I understood it meant that inline namespaces don't change the linkage property, so for example if you define a normal global variable or a constant with the keyword extern, they will have external linkage just like they would have had without the inline namespace.
So inline namespaces are apart of the global namespace and the namespace their identifier represents? Is that why the default call of
calls the the v1 version? (2nd example of Inline namespaces)
They're accessible via their surrounding namespace. In this case it's the global namespace, so you're right.
"Unnamed namespaces will also keep user-defined types (something we’ll discuss in a later lesson) local to the file, something for which there is no alternative equivalent mechanism to do."
I am learning from these tutorials linearly, so I don't know much of classes yet, please forgive me if you will answer my question later.
So classes can't have internal linkage?
Linkage is a property of objects, not type definitions. So while you can define a variable as internal via the static keyword, you can't use the static keyword to make a type local to a file (only objects of that type can be made local to the file).
One more,
Typo = "declare an normal namespace named v2"
Correction = "declare a normal namespace named v2"
Nitpicky? Maybe. But you're giving me a great tutorial for free. I want to do something to return the favor.
Typos fixed. Thanks for pointing them out.
Typo = "This might make unnamed namespaces seems useless."
Correction = "This might make unnamed namespaces seem useless."
I'm afraid I didn't get the point to differentiate between a global namespace and an inline namespace. What I understand is-
1.A namespace (global or local) allows multiple definitions, which an inline namespace allows too.
2.A global namespace has external linkage, which an inline namespace also does have (from what I read- "inline namespaces don’t give everything internal linkage").
Could you please let me know what I'm missing?
Inline namespaces essentially put their identifiers into both the inline namespace and the surrounding namespace. This can be useful in certain circumstances when code wasn't originally namespaced but you want to change that without necessarily rewriting all the uses of said code.
Hi,
Why we did not solve our problem (doSomething()) by putting the new function in a new namespace ??
________________________________________________
void doSomething(){
cout<<"v1\n";
}
namespace v2{
void doSomething(){
cout<<"v2\n";
}
}
we can solve this problem in this way, so why adding inline??
I only noticed now, but congrats to nascardriver for being promoted. Great job in editing the article!
Thanks :)
Thanks for going through these special types of namespaces... Namespaces are one of the things that I find unique to C++, so it's always good to learn more about it...
While I do find some use cases of anonymous namespaces, inline namespaces don't interest me that much because the main purpose of their existence is to provide some primitive form of versioning (which while useful) will never be used by any actual developer due to the presence of Version Control Systems like Git...
You're mixing up versioning of source code (git) with versioning of a library. Take the standard library for example. There's only 1 library, but it serves all versions of the standard (C++98 through C++2a). There's a neat example, including comments, on stackoverflow. It's going to be hard to understand the example, you might want to revisit it later.
If unnamed namespaces have internal linkage, why does this code doesn't compile :
Linkage has nothing to do with whether or not you can access something that's in the same file. Linkage defines if you can access something that's in a different file.
`a::test()` is inaccessible in files other than the file it's defined in.
You still have to use the `a::` prefix to access it in `main`.
What is the difference between putting something in an inline namespace vs. in the global scope?
Name collisions are easy to solve with inline namespaces:
Now you include something else that also has an inline namespace with the same function:
If both library authors put the functions in the global namespace, you'd have to edit the libraries or do some dirty workarounds.
> Unnamed namespaces will also keep user-defined type definitions (something we’ll discuss in a later lesson) local to the file, something for which there is no alternative equivalent mechanism to do.
Type definitions were discussed in a previous lesson, rather than a later one.
User-defined types (`struct`, `class`) are covered later. Either lessons were moved around and you read the lesson on `struct` already, or you're thinking of something else.