Namespaces in C

Why doesn't ANSI C have namespaces?

C does have namespaces. One for structure tags, and one for other types. Consider the following definition:

struct foo
{
int a;
};

typedef struct bar
{
int a;
} foo;

The first one has tag foo, and the later is made into type foo with a typedef. Still no name-clashing happens. This is because structure tags and types (built-in types and typedef'ed types) live in separate namespaces.

What C doesn't allow is to create new namespace by will. C was standardized before this was deemed important in a language, and adding namespaces would also threaten backwards-compatibility, because it requires name mangling to work right. I think this can be attributed due to technicalities, not philosophy.

EDIT:
JeremyP fortunately corrected me and mentioned the namespaces I missed. There are namespaces for labels and for struct/union members as well.

Namespaces in C

When using namespace prefixes, I normally add macros for the shortened names which can be activated via #define NAMESPACE_SHORT_NAMES before inclusion of the header. A header foobar.h might look like this:

// inclusion guard
#ifndef FOOBAR_H_
#define FOOBAR_H_

// long names
void foobar_some_func(int);
void foobar_other_func();

// short names
#ifdef FOOBAR_SHORT_NAMES
#define some_func(...) foobar_some_func(__VA_ARGS__)
#define other_func(...) foobar_other_func(__VA_ARGS__)
#endif

#endif

If I want to use short names in an including file, I'll do

#define FOOBAR_SHORT_NAMES
#include "foobar.h"

I find this a cleaner and more useful solution than using namespace macros as described by Vinko Vrsalovic (in the comments).

understanding C namespaces

C has four different name spaces for identifiers:

  • Label names (the goto type).
  • Tags (names of structures, unions and enumerations).
  • Members of structures and unions (these have a separate namespace per structure/union).
  • All other identifiers (function names, object names, type(def) names, enumeration constants, etc).

See also C99 6.2.3.

So your two question can be answered as:

  1. Yes, function names and typedef names share the same name space.
  2. No conflict, because the compiler will use scope rules (for function or object names). The identifier in main is said to shadow the global function name, something your compiler will warn you about if you set the warning levels high enough.

Is there a better way to express nested namespaces in C++ within the header

C++17 might simplify nested namespace definition:

namespace A::B::C {
}

is equivalent to

namespace A { namespace B { namespace C {
} } }

See (8) on namespace page on cppreference:

http://en.cppreference.com/w/cpp/language/namespace

extern C linkage inside C++ namespace?

Your code works, but you should beware that all functions that have extern "C" linkage share the same space of names, but that is not to be confused with the C++ notion of "namespace": Your function is really someNameSpace::doSomething, but you cannot have any other extern "C" function with unqualified name doSomething in any other namespace.

See 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. Two declarations for a variable with C
language linkage with the same name (ignoring the namespace names that qualify it) that appear in different
namespace scopes refer to the same variable. An entity with C language linkage shall not be declared with
the same name as a variable in global scope, unless both declarations denote the same entity; no diagnostic is
required if the declarations appear in different translation units. A variable with C language linkage shall not
be declared with the same name as a function with C language linkage (ignoring the namespace names that
qualify the respective names); no diagnostic is required if the declarations appear in different translation
units. [Note: Only one definition for an entity with a given name with C language linkage may appear in
the program (see 3.2); this implies that such an entity must not be defined in more than one namespace
scope. — end note]

Your company's or project's global style arbiters should be able to advise you on a suitable naming policy for your code base.

Why does c++'s namespace scope also include file scope(in c)?

The C++ standard doesn't mention file scope because it isn't trying to explain things in C terms. It defines and uses its own terms. In this case, it is under the definition of namespaces:

[basic.namespace]

2 The outermost declarative region of a translation unit is a
namespace; see [basic.scope.namespace].

This declarative region, in C++ terms, is the equivalent of C's file scope. The C++ standard uses these definitions because it intends to support namespace declarations, that allow us to partition this scope into smaller pieces.

C has no such feature, so it speaks only of things at file scope as the its outermost scope, because said definition is enough.



Related Topics



Leave a reply



Submit