By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,778 Members | 1,890 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,778 IT Pros & Developers. It's quick & easy.

Accessing anonymous namespace

P: n/a

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?
--

Frederick Gotham
Jun 30 '06 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Frederick Gotham <fg*******@SPAM.com> wrote:
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
Jun 30 '06 #2

P: n/a
Steve Pope posted:

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.

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.
--

Frederick Gotham
Jun 30 '06 #3

P: n/a
Frederick Gotham wrote:
Steve Pope posted:

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.

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.

Jul 1 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.