Accessing anonymous namespace

F

Frederick Gotham

Back in the day, if you wanted a function to be self-contained within a
translation unit, you defined the function as "static".

If there were an external linkage function by the same name residing in a
different translation unit, then the current translation unit was simply
oblivious to it and had no way of accessing it. Any time the function
name was mentioned in the current translation unit, it referred to the
"static" one which resides in the current translation.

Here's an example to demonstrate what I mean:

/* a.cpp */

int Func()
{
return 10;
}


/* b.cpp */

static int Func()
{
return 5;
}

int main()
{
Func(); /* This calls the internal function */

/* We have no way of accessing the external
linkage function. */
}


Also note that you can't put a forward declaration in "b.cpp" to the
effect of:

extern int Func();

(This gives a compile error on my system when followed by a static
function of the same name and signature.)

Now that we've moved on to anonymous namespaces, it seems that things
have changed a little. We can now access the external linkage function,
but at expense of not being able to access the internal linkage one (or
so I think?)

Here's the code:


/* a.cpp */

int Func()
{
return 10;
}


/* b.cpp */

int Func(); /* Grants us access to the external one */

namespace {

int Func()
{
return 5;
}

}


int main()
{
::Func(); /* Calls the external one*/

/* I don't think we've any way of calling
the internal one. */
}


If we omit the forward-declaration of "Func" at the beginning of "b.cpp",
then of course, we only have access to the internal one, and NOT to the
external one.


Any thoughts on this?
 
S

Steve Pope

Frederick Gotham said:
int Func(); /* Grants us access to the external one */

namespace {

int Func()
{
return 5;
}

}
int main()
{
::Func(); /* Calls the external one*/

/* I don't think we've any way of calling
the internal one. */
}
Any thoughts on this?

Yes. The contents of the nameless namespace are local to
one sourcefile, so whoever's coding that file is free to
choose whatever identifiers they like for names within that
namespace, and so is always free to use ones that do not
conflict with their own code.

So there doesn't seem to be much of a need for a mechanism
to get around this deficiency.

Steve
 
F

Frederick Gotham

Steve Pope posted:

Yes. The contents of the nameless namespace are local to
one sourcefile, so whoever's coding that file is free to
choose whatever identifiers they like for names within that
namespace, and so is always free to use ones that do not
conflict with their own code.

So there doesn't seem to be much of a need for a mechanism
to get around this deficiency.


Imagine this:

We have a load of header files pertaining to a particular library.
Everything in the library is defined in the global namespace (rather than
something like LibraryName::EatGrass() ).

In one of our own source files, we have a function within an anonymous
namespace called "EatGrass". This particular source file also happens to
contain "main". Here's how it looks at the moment:

namespace {

int EatGrass()
{
return 5;
}

}

int main()
{
EatGrass();
}


Later, we decide that we need something from the library, so we include a
header:

#include <somelibrary/consumption.hpp>

namespace {

int EatGrass()
{
return 5;
}

}

int main()
{
EatGrass();
}


Unfortunately now, we get a compile error because the function call is
ambiguous. Normally we'd rememdy this by placing the calling function
within the anonymous namespace also... but alas, the following give us a
linker error:


#include <somelibrary/consumption.hpp>

namespace {

int EatGrass()
{
return 5;
}

int main()
{
EatGrass(); /* Intends to call internal func */
}

}

int SomeOtherFunc()
{
EatGrass(); /* Intends to call external func */
}


Because we can't put "main" inside an anonymous namespace.
 
R

Rolf Magnus

Frederick said:
Steve Pope posted:




Imagine this:

We have a load of header files pertaining to a particular library.
Everything in the library is defined in the global namespace (rather than
something like LibraryName::EatGrass() ).

In one of our own source files, we have a function within an anonymous
namespace called "EatGrass". This particular source file also happens to
contain "main". Here's how it looks at the moment:

namespace {

int EatGrass()
{
return 5;
}

}

int main()
{
EatGrass();
}


Later, we decide that we need something from the library, so we include a
header:

#include <somelibrary/consumption.hpp>

namespace {

int EatGrass()
{
return 5;
}

}

int main()
{
EatGrass();
}


Unfortunately now, we get a compile error because the function call is
ambiguous. Normally we'd rememdy this by placing the calling function
within the anonymous namespace also... but alas, the following give us a
linker error:


#include <somelibrary/consumption.hpp>

namespace {

int EatGrass()
{
return 5;
}

int main()
{
EatGrass(); /* Intends to call internal func */
}

}

int SomeOtherFunc()
{
EatGrass(); /* Intends to call external func */
}


Because we can't put "main" inside an anonymous namespace.

The solution that Steve was thinking about is to simply rename the internal
EatGrass() to something else. That should be easy, because it is only used
in one file.
Another solution would be to put a named namespace into your anonymous one.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,994
Messages
2,570,223
Members
46,812
Latest member
GracielaWa

Latest Threads

Top