that this snippet of code actually do?
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
void test();
namespace {
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
}
int main(void) {
return 0;
}
void test() {
printf("testing function\n");
}
why does the test function actually get called? and why use the "anonymous" namespace? I found this piece of code in an open source project...
This:
static struct StaticStruct {
StaticStruct() {
test();
}
} TheStaticSupport;
Is equivalent to this:
struct StaticStruct {
StaticStruct() {
test();
}
};
static StaticStruct TheStaticSupport;
It defines a type named StaticStruct and an instance of the type named TheStaticSupport with internal linkage (though, since it is declared in an unnamed namespace, the static is redundant).
The constructor for TheStaticSupport is called before main() is entered, to construct the object. This calls the test() function.
The anonymous namespace gives the contained objects internal linkage, as their fully qualified name can never be known to anyone outside the translation unit. It's the sophisticated man's version of the old static in C.
Note that you do declare a global object of type StaticStruct, and its constructor (which runs before main() is called) calls test().
Related
This question got me wondering whether it is ever useful/necessary to fully qualify class names (including the global scope operator) in an out-of-class member function definition.
On the one hand, I've never seen this done before (and the syntax to properly do so seems obscure). On the other, C++ name lookup is very non-trivial, so maybe a corner case exists.
Question:
Is there ever a case where introducing an out-of-class member function definition by
ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) { ... }
would differ from
ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) { ... } (no global scope :: prefix)?
Note that member function definitions must be put into a namespace enclosing the class, so this is not a valid example.
A using-directive can cause Fully to be ambiguous without qualification.
namespace Foo {
struct X {
};
}
using namespace Foo;
struct X {
void c();
};
void X::c() { } // ambiguous
void ::X::c() { } // OK
It's necessary if one is a masochist and enjoys writing stuff like this
namespace foo {
namespace foo {
struct bar {
void baz();
};
}
struct bar {
void baz();
};
void foo::bar::baz() {
}
void (::foo::bar::baz)() {
}
}
One can of course write the second overload as foo::foo::bar::baz in global scope, but the question was whether or not the two declarations can have a different meaning. I wouldn't recommend writing such code.
If a using directive is used then there can be a confusing code.
Consider the following demonstrative program
#include <iostream>
#include <string>
namespace N1
{
struct A
{
void f() const;
};
}
using namespace N1;
void A::f() const { std::cout << "N1::f()\n"; }
struct A
{
void f() const;
};
void ::A::f() const { std::cout << "::f()\n"; }
int main()
{
N1::A().f();
::A().f();
return 0;
}
So for readability this qualified name
void ::A::f() const { std::cout << "::f()\n"; }
shows precisely where the function is declared.
[#PasserBy has found that my question is a duplicate. The question can be closed, thanks.]
How can I get a named namespace with internal linkage? That is, how can I get a named namespace invisible to external source files? I want this:
static namespace N {
int foo() {return 10;}
int bar() {return 20;}
}
However, unfortunately, C++ does not recognize static namespace.
Enclose the named namespace within an unnamed namespace:
namespace {
namespace N {
int foo() {return 10;}
int bar() {return 20;}
}
}
int sum()
{
return N::foo() + N::bar();
}
This works because an unnamed namespace automatically exports its members (the sole member in this case being the namespace N) to the surrounding scope—without exposing the members to other source files.
I was wondering, how I could set a const member variable of an unnamed namespace as a default function parameter where the function is declared in an named namespace.
Well I guess this is hard to explain for me, here is an example of what I want to do:
//foo.h
namespace foo
{
void justAFunction(std::string function_string = unnamed_str);
}
//foo.cpp
#include "foo.h"
namespace foo
{
namespace
{
const std::string unnamed_str = "simple string";
}
void justAFunction(std::string function_string)
{
...
}
}
This does not link...
I could still write the default parameter in the function definition, but that is not what I want, since the caller won't see it, right?
Any advice how to code this correct?
Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.
I have two namespaces defined in the default/"root" namespace, nsA and nsB. nsA has a sub-namespace, nsA::subA. When I try referencing a function that belongs to nsB, from inside of nsA::subA, I get an error:
undefined reference to `nsA::subA::nsB::theFunctionInNsB(...)'
Any ideas?
Use global scope resolution:
::nsB::TheFunctionInNsB()
#include <stdio.h>
namespace nsB {
void foo() {
printf( "nsB::foo()\n");
}
}
namespace nsA {
void foo() {
printf( "nsA::foo()\n");
}
namespace subA {
void foo() {
printf( "nsA::subA::foo()\n");
printf( "calling nsB::foo()\n");
::nsB::foo(); // <--- calling foo() in namespace 'nsB'
}
}
}
int main()
{
nsA::subA::foo();
return 0;
}
Need more information to explain that error. The following code is fine:
#include <iostream>
namespace nsB {
void foo() { std::cout << "nsB\n";}
}
namespace nsA {
void foo() { std::cout << "nsA\n";}
namespace subA {
void foo() { std::cout << "nsA::subA\n";}
void bar() {
nsB::foo();
}
}
}
int main() {
nsA::subA::bar();
}
So, while specifying the global namespace solves your current problem, in general it is possible to refer to symbols in nsB without it. Otherwise, you'd have to write ::std::cout, ::std::string, etc, whenever you were in another namespace scope. And you don't. QED.
Specifying the global namespace is for situations where there's another nsB visible in the current scope - for instance if nsA::subA contained its own namespace or class called nsB, and you want to call ::nsbB:foo rather than nsA::subA::nsB::foo. So you'd get the error you quote if for example you have declared (but not defined) nsA::subA::nsB::theFunctionInNsB(...). Did you maybe #include the header for nsB from inside namespace subA?