well, ok. I can plainly forward
#include "stuff"
int main ()
{
return megacorp:
rojectx::apps:myapp1::main ();
}
Yup, that's the best way to do it.
but for some obscure reasons, I first tried the former version,
found that it didn't work and then wanted to learn why.
it's tolarable to have the second version
another background was this: i do lot of templated stuff which
needs to be included with definitions anyway (when export is not
there ..). so i thought maybe i can rid of those nasty header
files altogether. i hate header files. why write code twice?
You're not writing code twice, just declarations. The separation is
quite important in very large projects, since .h files should rarely
be modified.
problem
of course with above example is that namespace scoped non-templated
functions may only be defined once (the obnoxious "One Definition Rule").
Not true if any of the following is true:
a) They are defined inside a class body.
b) They are declared inline.
c) They are in an anonymous namespace.
d) They are declared static.
this one i don't understand either: with namespace scoped templated
functions, having multiple (of course identical) definitions is
_separate_ translation units is allowed by the standard as far as
I know and no problem for the linker to sort out.
Actually it's quite a big problem for the linker to sort out - some
linkers can't do it (including one I have used on QNX - .exes ended up
containing multiple definitions of template functions, causing
horrendous bloat). Some compilers have complicated prelinkers that get
around this problem, by assigning each template instantiation to a
particular translation unit, but this requires multiple compilation
passes to find out all the required instantiations. This is what
Comeau C++ does by default.
If you have multiple definitions of a function, either the
compiler/linker has to compile them all, assume they are the same and
discard all but one, or it has to assign the definition to a single
translation unit and not compile it in any of the others. You can
imagine the number of passes that would require!
One way around the bloat issue is just to have a single compilation
unit for your whole program! This might suit you.
same goes for const
vars, structs, classes, typedef, ... but NOT plain functions. why?
const vars have static linkage, so you haven't got multiple
definitions, rather each translation unit gets a separate copy. For
static functions this will obviously lead to major code bloat.
IOW: how do i get rid of headers
Well, I suggested some ways above, but none of them are recommended
since they all lead to bloated executables - the linker knows to merge
different instantations of template functions, but not normal ones.
sideconditions:
i dont care a lot on compilation speed .. i don't develop
million line programs .. i just go buy more Ghz
It's not just compilation speed. It's the fact that any change at all
means you have to recompile absolutely everything.
i also dont care about "users" seeing ugly definitions instead
of a "pure" interface in separate headers. users should consult
the (doxygen generated) docs anyway .. not look at code.
Yes, I don't strongly disagree with that, but the biggest problem is
the dependency bottleneck. You will have major problems with circular
dependencies if you're not careful.
in java, nobody complaints ..
Actually, they do. Look up posts by James Kanze on the subject, for
one.
It's best not to fight the language - in Java do what it wants, in C++
do what it wants.
Tom