Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

As a non-C programmer, why would "header only" be a good thing?


It's not.

It's a tradeoff people make between ease of integration - just download the .h file into your project folder and #include it in your source file instead of worrying about source build system vs target build system, cross compiling headaches etc...

And compilation times: any time you change any of your source files, your compiler also has to recompile your dependencies. (Assuming you haven't used precompiled headers).


I'm completely ignorant about this, but wouldn't it be possible to compile separately your project to improve compilation times? for instance, if you're using OP's vector library, which is self contained, you could compile that first and just once?


Let's say you need to use a function like:

    int add(int a, int b){
        // Long logic and then this
        return a+b;
    }
Let's say this is your main.c.

    #include "add.h"

    int main(void) {
      return add(5,6);
    }

The preprocessor just copies the contents of add.h into your main.c whenever you're trying to compile main.c. (let's ignore the concept of precompiled headers for now).

What you can instead do is just put the add function declaration in add.h that just tells the compiler that add function takes two integers and returns an integer.

   int add(int a, int b);
You can then put the add function definition in add.c , compile that to an add.o and link it to your main.o at link time to get your final binary - without having to recompile add.o every time you change your main.c.

Precompiled headers: https://maskray.me/blog/2023-07-16-precompiled-headers


Unless you have link time optimization you would lose out on optimization and performance.

The whole thing is essentially a workaround for lack of sufficiently good/easy ways to package code in the ways people want to use it.


Recompiling the dependencies should only really happen if you change the file with the implementation include (usually done by defining <library>_IMPLEMENTATION or something like that.


It often also means it was written more correctly. There is a bit of an art to designing a header only library and it can strike a different balance between code size and runtime speed optimization.

In strict terms when you place implementation in a .c file you probably want that code to be shared when different things call it, and the compiler will "link" to that same implementation.

When you have a header only library the compiler is free to optimize in more ways specific to your actual use case.


Extremely easy copy paste deployment into projects


C's package management story is unfriendly to say the least. A header only library simplifies it dramatically, and makes it much more straightforward to integrate dependencies into your application.


Using your OS' package manager IS C's package management. Is it really that difficult to use apt, pacman, or BSD's "pkg"?


This. Wish I could upvote this 10 times.


What if I'm using 10 different OS?

I can still push the file on git and it works everywhere else.


git is not a package manager. It does not handle many things a package manager does.


GP never said it was.

But it does successfully replaces the need of using one, with less problems for certain situations.


Yes, I do use git submodules as well sometimes.

If you do not need the features of a package manager, then git submodules is great indeed.


The reply was also not about submodules. “Push” makes it clear.


That makes it even worse! If it is not submodules, then it is just copying a file into a repo with no version tracking against upstream, no update path, and no way to even know when there is a security fix.

Package managers already use git where appropriate under the hood. Arch's PKGBUILD sources pull from git repos, FreeBSD's ports can fetch from git, Gentoo ebuilds support git-r3. The fetching is not the hard part. What a package manager gives you on top of that is dependency resolution, version constraints, conflict detection, reproducible builds, and clean removal. "git push" gives you none of that.

And since I did not really address kreco's point properly: if the concern is cross-platform support across many OSes, tools like vcpkg and Conan exist specifically for this: cross-platform C/C++ dependency management with one workflow regardless of target. pkgsrc runs on 20+ platforms with the same build recipes. A header file in a git repo gives you none of that, it just gives you the illusion of portability until you hit a platform where it does not compile or links against the wrong thing.

If your workflow does not need any of those features, then yeah, sure, but then you are not solving C's "package management problem", you are just ignoring it.

In any case, the original comment called C's package management "unfriendly", and the counter-argument has somehow arrived at "just copy files into your repo and push". Comparing that to what a package manager does is absurd.


I don't think either me or GP compared this to a package manager. "Replacing usage" doesn't mean "it's the same".



That's just pushing a file to git.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: