Is there any way to not have to write function declarations twice (headers) and still retain the same scalability in compiling, clarity in debugging, and flexibility in desi
There's header file generation software. I've never used it, but it might be worth looking into. For instance, check out mkhdr! It supposedly scans C and C++ files and generates the appropriate header files.
(However, as Richard points out, this seems to limit you from using certain C++ functionality. See Richard's answer instead here right in this thread.)
You can carefully lay out your functions so that all of the dependent functions are compiled after their dependencies, but as Nils implied, that is not practical.
Catalin (forgive the missing diacritical marks) also suggested a more practical alternative of defining your methods in the header files. This can actually work in most cases.. especially if you have guards in your header files to make sure they are only included once.
I personally think that header files + declaring functions is much more desirable for 'getting your head around' new code, but that is a personal preference I suppose...
It's completely possible to develop without header files. One can include a source file directly:
#include "MyModule.c"
The major issue with this is one of circular dependencies (ie: in C you must declare a function before calling it). This is not an issue if you design your code completely top-down, but it can take some time to wrap ones head around this sort of design pattern if you're not used to it.
If you absolutely must have circular dependencies, one may want to consider creating a file specifically for declarations and including it before everything else. This is a little inconvenient, but still less pollution than having a header for every C file.
I am currently developing using this method for one of my major projects. Here is a breakdown of advantages I've experienced:
I've discovered that Gish (a game by Cryptic Sea, Edmund McMillen) used a variation on this technique inside its own source code.
I felt the same way when I started writing C, so I also looked into this. The answer is that yes, it's possible and no, you don't want to.
First with the yes.
In GCC, you can do this:
// foo.cph
void foo();
#if __INCLUDE_LEVEL__ == 0
void foo() {
printf("Hello World!\n");
}
#endif
This has the intended effect: you combine both header and source into one file that can both be included and linked.
Then with the no:
This only works if the compiler has access to the entire source. You can't use this trick when writing a library that you want to distribute but keep closed-source. Either you distribute the full .cph file, or you have to write a separate .h file to go with your .lib. Although maybe you could auto-generate it with the macro preprocessor. It would get hairy though.
And reason #2 why you don't want this, and that's probably the best one: compilation speed. Normally, C sources files only have to be recompiled when the file itself changes, or any of the files it includes changes.
When all your files are combined header and source files, every change will trigger a recompile of all source files. C++ isn't known for its fast compile times even now, imagine what would happen when the entire project had to be recompiled every time. Then extrapolate that to a project of hundreds of source files with complicated dependencies...
You can avoid headers. Completely. But I don't recommend it.
You'll be faced with some very specific limitations. One of them is you won't be able to have circular references (you won't be able to have class Parent contain a pointer to an instance of class ChildNode, and class ChildNode also contain a pointer to an instance of class Parent. It'd have to be one or the other.)
There are other limitations which just end up making your code really weird. Stick to headers. You'll learn to actually like them (since they provide a nice quick synopsis of what a class can do).
I understand your problems. I would say that the C++ main problem is the compilation/build method that it inherited from the C. The C/C++ header structure has been designed in times when coding involved less definitions and more implementations. Don't throw bottles on me, but that's how it looks like.
Since then the OOP has conquered the world and the world is more about definitions then implementations. As the result, including headers makes pretty painful to work with a language where the fundamental collections such as the ones in the STL made with templates which are notoriously difficult job for the compiler to deal with. All those magic with the precompiled headers doesn't help so much when it comes to TDD, refactoring tools, the general development environment.
Of course C programmers are not suffering from this too much since they don't have compiler-heavy header files and so they are happy with the pretty straightforward, low-level compilation tool chain. With C++ this is a history of suffering: endless forward declarations, precompiled headers, external parsers, custom preprocessors etc.
Many people, however, does not realize that the C++ is the ONLY language that has strong and modern solutions for high- and low-level problems. It's easy to say that you should go for an other language with proper reflection and build system, but it is non-sense that we have to sacrifice the low-level programming solutions with that and we need to complicate things with low-level language mixed with some virtual-machine/JIT based solution.
I have this idea for some time now, that it would be the most cool thing on earth to have a "unit" based c++ tool-chain, similar to that in D. The problem comes up with the cross-platform part: the object files are able to store any information, no problem with that, but since on windows the object file's structure is different that of the ELF, it would be pain in the ass to implement a cross-platform solution to store and process the half-way-compilation units.