C++ Namespaces

UralTerpsichore

Weaksauce
Joined
Apr 28, 2002
Messages
71
I'm reorganizing some of my more commonly used functions into their own namespace, and I have a question about how to organize the files. I want to add in the function headings into utility.h, and then the implementation into utility.cpp, all under the SPUtility namespace.

In the utility.h file, should I write it out as
Code:
namespace SPUtility{
float foo();
int bar();
}

and then in the utility.cpp file
Code:
float SPUtility::foo(){...}
or should I do
Code:
namespace SPUtility{
float foo()
{
...
}

...
}

Thanks for the help.
 
This question has nothing whatsoever to do with namespaces.

Option two won't work. It violates the ODR (One Definition Rule). If a header which defines a non-inline function is included by two .cc files, you die violently. Header guards don't help you.

Only declarations and inline definitions may appear in headers.

You have the following three options:

[Traditional Separate Compilation]
Code:
foo.hh:
void mlar();

foo.cc:
void mlar() {
    destroy_world();
}

[Header-Only Code]
Code:
foo.hh:
inline void mlar() {
    destroy_world();
}

[Header-Only Code With Prototypes]
Code:
foo.hh:
inline void mlar();
inline void oink();

// Lots of other stuff

inline void mlar() {
    oink();
}

// More definitions

Note that templates can't be separately compiled. They have to be inline. (Warning to export pedants: You all suck.)

I basically use header-only code with prototypes for everything that I do. Separate compilation sucks. It's way easier to use a library when you just have to include the headers.
 
Ack, now that I review my original post, I realize I goofed my question a bit. The two options were how to write the implementation in the .cpp file when the declarations were made in a namespace, not how to do the whole thing.

As it is, turns out option #1 is still the way to go, just as long as you're not porting over buggy C code that the C++ linker freaks out at :D
 
Originally posted by Daemon1313
Gad talk about an overly complex answer to a simple question.

Yea, because answering "one" or "two" would have really explained a whole lot.
 
Originally posted by STL
This question has nothing whatsoever to do with namespaces.
The question has everything to do with namespaces.

Originally posted by STL
Option two won't work. It violates the ODR (One Definition Rule). If a header which defines a non-inline function is included by two .cc files, you die violently. Header guards don't help you.
The OP states that he is using separate compilation, he asks whether he should prefer to reopen the namespace in the implementation file (option 2) or use explicit qualification in the implementation file (option 1). To my knowledge the techniques produce identical results, though different programmers and coding standards may prefer one or the other.

Reopening the namespace (option 2) has the benefit of reinforcing the fact that the function or variable is a namespace member rather than a class member, but does not mention the namespace name with each member. Explicit qualification mentions the namespace name with each member definition but uses the same syntax as out-of-class-definition class member definitions (the reader who sees int foo::baz() cannot, by examining the local code, know whether foo is a class or namespace, though this is hardly a unique situation in C++).

Originally posted by STL
Note that templates can't be separately compiled. They have to be inline. (Warning to export pedants: You all suck.)

I basically use header-only code with prototypes for everything that I do. Separate compilation sucks. It's way easier to use a library when you just have to include the headers.
Separate compilation has its place as does header-only library code. Separately compiled code will, in general, minimize the size of your recompiles, it will also let you force an implementation to appear in one and only one module (for example when using dynamic libraries, which do not fall within the scope of C++, but do fall in the scope of programming real world systems). Also note that you can force the compiler to instantiate a template witnin one compilation unit and use the template in other compilation units without needing the member function definitions in the other units (though the code to accomplish this will vary from one compiler to another).

In my experience, header-only libraries are easier to integrate with existing projects and are the only reasonable method of distributing a template-only library. You should note that header-only libraries are vulnerable to more complicated ODR violations (current compilers detect some ODR violations but do not detect others) and, in general, only a very experienced library author can write libraries that make it easy for users to obey the ODR.
 
[MonkeyShave]
> The question has everything to do with namespaces.

As I read it, it didn't.

The OP later noted that his question was just how to define a function in a .cc when the function had been declared in an .hh as living in a namespace. In that case, the question is related to namespaces, and it is significantly easier to answer.

[STL]
> Option two won't work. It violates the ODR (One Definition Rule).
> If a header which defines a non-inline function is included by
> two .cc files, you die violently. Header guards don't help you.

[MonkeyShave]
> The OP states that he is using separate compilation

As I read it, I thought his Option 2 was to be placed in an .hh. That violates the ODR big-time.

> he asks whether he should prefer to reopen the namespace in the
> implementation file (option 2) or use explicit qualification in the
> implementation file (option 1).

Since he thought Option 2 should go in a .cc, they are equivalent. Option 1 is the traditional way to do things.

> Reopening the namespace (option 2) has the benefit of reinforcing
> the fact that the function or variable is a namespace member rather
> than a class member

In one naming scheme (the one I used to use), namespaces should be all lowercase: std, boost, nuwen. Classes should be InitialCapitals: MommySocket, SuffixTree, Phaser. Then the difference between classes and namespaces is obvious.

In the other naming scheme (the one that I use now), namespaces should be all lowercase: std, boost, nuwen. Classes should be lowercase_separated_by_underscores: suffix_tree, mommy_socket, phaser. Single-word classes then look like namespaces at first glance, but in practice this is not a difficulty (since namespaces are few and easy to remember).

> Separate compilation has its place as does header-only library
> code.

Yeah, yeah. I still don't have to like it.

> Separately compiled code will, in general, minimize the size of
> your recompiles

But compilation is fast! (Yes, I know it isn't for large projects.)

> Also note that you can force the compiler to instantiate a template
> witnin one compilation unit

Explicit instantiation is mlar.

> (though the code to accomplish this will vary from one compiler to
> another).

No, this can be done in a strictly conforming manner. It's just silly.

> You should note that header-only libraries are vulnerable to more
> complicated ODR violations

If you make everything inline and don't do something silly like make the code rely on macros which are defined differently in different translation units, you should be fine.

> in general, only a very experienced library author can write
> libraries that make it easy for users to obey the ODR.

Nah, it's easy.
 
Originally posted by STL
[MonkeyShave]
> The question has everything to do with namespaces.

As I read it, it didn't.

The OP later noted that his question was just how to define a function in a .cc when the function had been declared in an .hh as living in a namespace. In that case, the question is related to namespaces, and it is significantly easier to answer.

[STL]
> Option two won't work. It violates the ODR (One Definition Rule).
> If a header which defines a non-inline function is included by
> two .cc files, you die violently. Header guards don't help you.

[MonkeyShave]
> The OP states that he is using separate compilation

As I read it, I thought his Option 2 was to be placed in an .hh. That violates the ODR big-time.

> he asks whether he should prefer to reopen the namespace in the
> implementation file (option 2) or use explicit qualification in the
> implementation file (option 1).

Since he thought Option 2 should go in a .cc, they are equivalent. Option 1 is the traditional way to do things.

> Reopening the namespace (option 2) has the benefit of reinforcing
> the fact that the function or variable is a namespace member rather
> than a class member

In one naming scheme (the one I used to use), namespaces should be all lowercase: std, boost, nuwen. Classes should be InitialCapitals: MommySocket, SuffixTree, Phaser. Then the difference between classes and namespaces is obvious.

In the other naming scheme (the one that I use now), namespaces should be all lowercase: std, boost, nuwen. Classes should be lowercase_separated_by_underscores: suffix_tree, mommy_socket, phaser. Single-word classes then look like namespaces at first glance, but in practice this is not a difficulty (since namespaces are few and easy to remember).
I see what you're saying now, as I look back, I also jumped to conclusions when I read the OP, as I've usually used option 2 to define namespace members (I use many unnamed namespaces, and option 1 doesn't work for those).

Originally posted by STL
> Separate compilation has its place as does header-only library
> code.

Yeah, yeah. I still don't have to like it.

> Separately compiled code will, in general, minimize the size of
> your recompiles

But compilation is fast! (Yes, I know it isn't for large projects.)

> Also note that you can force the compiler to instantiate a template
> witnin one compilation unit

Explicit instantiation is mlar.

> (though the code to accomplish this will vary from one compiler to
> another).

No, this can be done in a strictly conforming manner. It's just silly.

> You should note that header-only libraries are vulnerable to more
> complicated ODR violations

If you make everything inline and don't do something silly like make the code rely on macros which are defined differently in different translation units, you should be fine.

> in general, only a very experienced library author can write
> libraries that make it easy for users to obey the ODR.

Nah, it's easy.
I have found some uses for explicit instantiation, for example in a large system which uses C++ dynalibs (to ensure that cross-module types share the same implementation). On the other hand, you're quite correct, you can explicitly instantiate a template within the standard, what you can't do is suppress instantiation in other translation units (within the standard), though many compilers provide extensions to accomplish this (of course if it were my own code, I could provide two headers, only one of which included member function definitions.

I'm still not convinced about the ease of writing ODR safe headers, as long as you avoid using declarations and directives and fully-qualify everything, you'll probably avoid the obvious mistakes, but the client code could still provide a specialization for, for example, std::swap and your template library could fail to meet the ODR in a manner which current compilers would not detect.
 
Back
Top