Having the code in the header gives a bit more flexibility considering the file layout. IMHO this is an awkward consequence of the missing de-facto-standard in C/C++ build systems.
Having the code in the header gives a bit more flexibility considering the file layout. IMHO this is an awkward consequence of the missing de-facto-standard in C/C++ build systems.
I hate this idiom every time I come across it. I like to look at the header file to see the interface and important documentation, and this just obscures it. Depending on your compiler it can make debugging a huge pain as well.
I had no idea that cmake would do this, after reading quite a lot of things about cmake v.s. make and how to write various makefiles for them. I posit that the C build tools are fundamentally hard to comprehend.
Blindly trusting it will lead to the same outcome, regardless of the programming language ecosytem.
Besides that was just one example, there are plenty of them with turing complete languages.
If you embed the source in your project, the terribleness is about adding to your Makefile:
funkylib.o: funkylib.c
$(CC) $<
myfinalexe: ... funkylib.o ...
# your existing executable creation (linking) commandThis still works nicely: the important stuff (documentation and public interface) is at the top, followed by the 'unimportant' implementation at the botton of the file.
STB-style headers are a bit different from typical C++ 'single header libraries' in that they put the declaration and implementation into separate sections in the header file (with the implementation inside an #ifdef/#endif pair), while C++ headers are usually a wild mix of class declarations intermixed with implementation code in template and inline functions (which is indeed harder to read).
I don't quite understand how debugging is affected? E.g. there are (usually) no inline functions in STB-style headers.
Again, this is different from typical C++ single-header-libraries (e.g. pretty much all C++ stdlib headers) where the implementation code is inlined or in template code.
A hack designed by those that cannot be bothered to modularize a build with binary libraries.
The fact that one has to learn complex build tools (and often multiple ones), is the sad thing here. Luckily there are also unity builds, which are extremely handy in many contexts, because they are so fast and easy to use between different platforms without having to deal with annoying external tools.
It's just easier to have a single .h you include.
No, it can be in a single place and you can just #include it.
>This .h will need to know if it got included multiple times, and so isn't just a trivial declaration.
This is the point of using header guards.
>It's just easier to have a single .h you include.
Depending on the build tool it's the same or only marginally easier (you save like 10 characters)
All code that would otherwise live in .c files is between an #ifdef/#endif block which is only activated in a single compilation unit in the whole project.
Not sure how this approach would lead to redundant "function definitions" which would need to be deduped by the linker. The only overhead is in the preprocessor for skipping the implementation block, but that happens pretty much at IO speed - it's not comparable with the parsing overhead in typical C++ headers with template and inline code.
Still, it seems like an ugly kludge to cope with a breathtakingly antiquated way of doing things.
What ever happened to keeping it simple?
I think it's mainly a fix/workaround for the breathtakingly antiquated build systems in the C/C++ world ;)
In the end, STB-style single-header vs. a single .h/.c pair is not all that different, both are equally straightforward to integrate into a project.
The actual problem are libraries made of dozens/hundreds/thousands of header and source files and coming with their own complex build system setup.