Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to insert a global name into a namespace and make it available only from that namespace?

Let's say I have a function with "C" linkage in global scope.

extern "C" int fun(int);

Then if I want to make it visible in a namespace I would do:

namespace foo {
   using ::fun;
}

But after this I am still able to call it as ::fun(0) in addition to foo::fun(0).

So my question is, is there a way to disallow the call from the global namespace for function fun and only allow it to be called from namespace foo?

like image 708
DeiDei Avatar asked Sep 20 '16 20:09

DeiDei


People also ask

Are namespaces global?

A namespace combines multiple file systems into one global file system.

What is global namespace in Python?

The global namespace contains any names defined at the level of the main program. Python creates the global namespace when the main program body starts, and it remains in existence until the interpreter terminates. Strictly speaking, this may not be the only global namespace that exists.

What is global namespace in C#?

:: operator (C# reference) The global namespace is the namespace that contains namespaces and types that are not declared inside a named namespace. When used with the :: qualifier, the global alias always references the global namespace, even if there is the user-defined global namespace alias.

What is the proper keyword for importing a namespace into a existing namespace?

using keyword allows you to import an entire namespace into your program with a global scope. It can be used to import a namespace into another namespace or any program. We imported the namespace X into namespace Y , hence class Check will now be available in the namespace Y .


1 Answers

The standard clearly establishes that the external C function is declared within a namespace, even if C doesn't know namespaces:

7.5/4: A linkage specification does not establish a scope. A linkage-specification shall occur only in namespace scope.

So instead of declaring the function in the global namespace, you could very well define it directly in your foo namespace:

// no declaration in global namespace, but... 
namespace foo {
    extern "C" int fun();
}

You could then refer to this function only via the namespace:

foo::fun();  // yes !
::fun();     // doesn't compile !!!

Note that you could even declare the external C function in several namespaces. They would all refer to the same C function:

namespace bar {
    extern "C" int fun();
}
...
foo::fun();  // ok
bar::fun();  // ok - same result as foo::fun(); 

This is guaranteed by the standard :

7.5/6: At most one function with a particular name can have C language linkage. Two declarations for a function with C language linkage with the same function name (ignoring the namespace names that qualify it) that appear in different namespace scopes refer to the same function.

Note that if the extern function was declared in the global namespace in one compilation unit due to some specific constraints, you could still organize that this declaration is not seen in the other compilation units where you would use your local namespace. This is perfectly valid according to the standard statement above. However, some care would be needed if you play with different visibility in different compilation units !

like image 100
Christophe Avatar answered Oct 02 '22 17:10

Christophe