Single file or header only libraries were really useful before C++ had package managers. There's conan now. I think microsoft has some tools for that too - vcpkg or nuget
They are still general very easy to install. Also, C programmers don't seem to use any package managers other than the default system package manager and maybe git sub-modules (at least, not that I know of).
C on Unices is very well served by pkg-config[1] and its reimplementations[2,3]. (The last of these should also work well with MSYS2 on Windows, but it’s not—yet?—widely used in that environment.) The nice thing is that it has no opinions on your build system or even package manager, it’s purely for package discovery at build time.
> Also, C programmers don't seem to use any package managers other than the default system package manager and maybe git sub-modules (at least, not that I know of).
For what it's worth, as someone who primarily writes C, not C++, I use the system package manager, vendoring, and sometimes Git submodules, depending on the project. On Windows, when I'm using MSYS2, I use the pacman package manager. If I'm targeting MSVC, I use CMake. For CMake, on Windows, I create my own directory where I place prebuilt dependencies for CMake to find [1]. With this approach, I can rely on CMake's builtin find_package behavior (no need for vcpkg and configure-time toolchain flags).
One problem is that there's too many to choose from, so there might just as well be none from a library author's point of view.
It's the same problem with putting build system files into your library source distribution - which build system to pick?
Libraries that come as a header, or a small number of headers and source files have none of those problems because they are trivial to integrate without requiring package manager or build system magic.
E.g. only top level projects should pick a specific build system and package manager, but not libraries.
Just this month I saw yet another sufferer of the consequences of disparate build systems. This resulted in a mixture of GCC and LLVM, which disagreed on the basic ABI for C enums for unknown/none-platform ARM. (ARM's ABI gives multiple options, leaving the choice of which option to use to the platform ABI... which for unknown/none is obviously missing.)
While I consider single-header libs overkill for my own taste in authoring things, I can't deny their continued ease of use in consumption. They're still useful. Sadly. If only because it won't be yet another source of debugging and fixing on my part when coworkers less familiar with integrating 3rd party dependencies into "our" build system either mess things up, or foist that work onto me - introducing delays and reducing bus factor.
Indeed, from a longterm maintenance perspective mitigating dependencies has advantages, and greatly simplifies porting.
For example, the answer to "how do we build this on architecture X?"... should not be install 28000 source files, and wait 3 days to discover half of the packages broke the build... because fork you that's why. lol =3
there is no build system that everyone has installed/is familiar w, single header libraries are as portable as C or UTF-8 itself are (so still the best choice), the only other alternative i see it using C itself as build system (i mean why not)
There's a kind of hn comment that pops up very frequently - aspirational/delusional/out of touch: people repeating hype as truth that no one that actually lives in the space would repeat.
Stuff like this (lol I don't know a single serious C++ project using conan/vcpkg/etc), or that mojo has replaced all of Python/C/C++ (not will replace but has!), or that Rust has replaced C/C++, or the LLMs have obviated everything.
I have no clue how someone can both be so clueless and yet so sure.
This is dogmatism, or "speaking in absolutes", and it's extremely common with pseudo-intellectuals in general.
The Dunning-Kruger effect also applies to smart people. You don't stop when you are estimating your ability correctly. As you learn more, you gain more awareness of your ignorance and continue being conservative with your self estimates.
My own take on this:
I think real intelligence by definition requires humility. One has to realize that we can't know the things we don't know, which includes the fact that we can't always trust our own beliefs and opinions because we might be relying on faulty or incomplete information, or we might be suffering from a mental health problem, whether we are aware of it or not.
"As a rule, strong feelings about issues do not emerge from deep understanding." -Sloman and Fernbach
I know this is only a sample size of 1 but I have never heard of any C or C++ developer using a package manager like conan/vcpkg/nuget, and I am assuming those are mostly used on Windows anyways.
Amazing how the same people will go nuts for header-only C++ libraries, but the moment you involve an .a file, say "Noooo! you can't just vendor your dependencies! You need eight zillion apt dependencies!"
Container images are also just a worse version of static linking (giving you all of the downsides and missing several upsides). Ideally the industry moves to something like nix for most purposes, and static linking is used for embedded systems and teaching.
These libraries are not compiled, packaged or distributed on their own; you have to include their code directly as part of your C/C++ game or app. You acquire and update them using git.
And if not using git, just fiddle around with a scripting language to automate the update, like check github's release API to see if there was some change between your local and the remote version somehow.
These do not seem to be pure "header-only", but involve #include-ing the same file at least once with "#define C2_xxx_IMPLEMENTATION 1"
That's fine though. AFAIK, there is no sane way (across platforms) to have singletons, and that involves some of the the trick above, unless you know someother way
I was just taking a look and couldn't help but notice the switch statement for your operator[], which likely causes a lot of unnecessary bad speculation at runtime:
Many believe the C++ compiler will magically optimize the switch away, but in some cases, like the example above for CLHEP, it doesn't happen, so you end up with bad performance.
38 comments
[ 2.1 ms ] story [ 91.2 ms ] threadhttps://github.com/nothings/stb
Microsoft really does not want you to do this, but they still allow it.
[1] https://www.freedesktop.org/wiki/Software/pkg-config/
[2] http://pkgconf.org/
[3] https://nullprogram.com/blog/2023/01/18/
For what it's worth, as someone who primarily writes C, not C++, I use the system package manager, vendoring, and sometimes Git submodules, depending on the project. On Windows, when I'm using MSYS2, I use the pacman package manager. If I'm targeting MSVC, I use CMake. For CMake, on Windows, I create my own directory where I place prebuilt dependencies for CMake to find [1]. With this approach, I can rely on CMake's builtin find_package behavior (no need for vcpkg and configure-time toolchain flags).
[1] https://cmake.org/cmake/help/latest/command/find_package.htm...
It's the same problem with putting build system files into your library source distribution - which build system to pick?
Libraries that come as a header, or a small number of headers and source files have none of those problems because they are trivial to integrate without requiring package manager or build system magic.
E.g. only top level projects should pick a specific build system and package manager, but not libraries.
Just this month I saw yet another sufferer of the consequences of disparate build systems. This resulted in a mixture of GCC and LLVM, which disagreed on the basic ABI for C enums for unknown/none-platform ARM. (ARM's ABI gives multiple options, leaving the choice of which option to use to the platform ABI... which for unknown/none is obviously missing.)
While I consider single-header libs overkill for my own taste in authoring things, I can't deny their continued ease of use in consumption. They're still useful. Sadly. If only because it won't be yet another source of debugging and fixing on my part when coworkers less familiar with integrating 3rd party dependencies into "our" build system either mess things up, or foist that work onto me - introducing delays and reducing bus factor.
For example, the answer to "how do we build this on architecture X?"... should not be install 28000 source files, and wait 3 days to discover half of the packages broke the build... because fork you that's why. lol =3
Stuff like this (lol I don't know a single serious C++ project using conan/vcpkg/etc), or that mojo has replaced all of Python/C/C++ (not will replace but has!), or that Rust has replaced C/C++, or the LLMs have obviated everything.
I have no clue how someone can both be so clueless and yet so sure.
who did i call a name?
The Dunning-Kruger effect also applies to smart people. You don't stop when you are estimating your ability correctly. As you learn more, you gain more awareness of your ignorance and continue being conservative with your self estimates.
My own take on this:
I think real intelligence by definition requires humility. One has to realize that we can't know the things we don't know, which includes the fact that we can't always trust our own beliefs and opinions because we might be relying on faulty or incomplete information, or we might be suffering from a mental health problem, whether we are aware of it or not.
"As a rule, strong feelings about issues do not emerge from deep understanding." -Sloman and Fernbach
nah it's just gossip. they read something spicy about C++ or Mojo or LLMs and they jump at the chance to repeat it.
I'm always suspicious of "Professional" in descriptions like this as it is a meaningless word you add to make it sound impressive.
Also, in this case it means a 900 line math library with 78 lines of tests...
The fact that invert_safe() isn't actually safe isn't the greatest look here though.
Header-only libraries are static linking.
I'm sure I've also spotted him in the SDL channels.
https://github.com/RandyGaul/cute_framework
That's fine though. AFAIK, there is no sane way (across platforms) to have singletons, and that involves some of the the trick above, unless you know someother way
If you do, please add your idea here - https://github.com/open-telemetry/opentelemetry-cpp/issues/2... - "Header only singletons are not working properly for Windows #2534"
https://github.com/RandyGaul/cute_headers/blob/755849fc2819d...
I fixed this exact problem in a highly used library in high energy physics:
https://gitlab.cern.ch/CLHEP/CLHEP/-/commit/5f20daf0cae91179...
Many believe the C++ compiler will magically optimize the switch away, but in some cases, like the example above for CLHEP, it doesn't happen, so you end up with bad performance.
https://github.com/RandyGaul/cute_headers/blob/755849fc2819d...
See an optimized quaternion multiplication implementation in SSE by me here:
https://stackoverflow.com/questions/18542894/how-to-multiply...