What does HackerNews think of stb?

stb single-file public domain libraries for C/C++

Language: C

Godot.

C++ and SDL2 will get you a window, events, sound and other low level stuff, and you can get support for PNGs and fonts easier by including some of nothings/stb libraries[0] (rather than the equivalent SDL libs.) Maybe toss in Lua/LuaJIT for good measure. That will scratch a lot of itches.

But IMHO it's better in the long run to just pick up Godot and save yourself months of unnecessary effort. Otherwise if you're like me you'll wind up in the weeds with nothing to show for it but a tilemap class you've rewritten a dozen times.

[0]https://github.com/nothings/stb

The guy who developed stb_image writes all his software on Visual C++ 6 from 1998

https://github.com/nothings/stb

> Why not C99? stdint.h, declare-anywhere, etc.

> I still use MSVC 6 (1998) as my IDE because it has better human factors for me than later versions of MSVC.

> The CRC and the compression are non-trivial. CRC is a table and 5 lines of code. That's trivial.

>zlib is 23k lines

It's not needed to make a PNG reader/writer. zlib is massive overkill for only making a PNG reader or writer. Here's a tiny deflate/inflate code [2] under 1k lines (and could be much smaller if needed).

stb[0] has single headers of ~7k lines total including all of the formats PNG, JPG, BMP,. PSD, GIF, HDR, and PIC. Here's [1] a 3k lines single file PNG version with tons if #ifdefs for all sorts of platforms. Removing those and I'd not be surprised if you could not do it in ~1k lines (which I'd consider quite simple compared to most of todays' media formats).

>Of course they're not common formats so you're stuck with complex formats like PNG

BMP is super common and easy to use anywhere.

I use flat image files all the time for quick and dirty stuff. They quickly saturate disk speeds and networking speeds (say recording a few decent speed cameras), and I've found PNG compression to alleviate those saturate CPU speeds (some libs are super slow, some are vastly faster). I've many times made custom compression formats to balance these for high performance tools when neither things like BMPs or things like PNG would suffice.

[0] https://github.com/nothings/stb

[1] https://github.com/richgel999/fpng/blob/main/src/fpng.cpp

[2] https://github.com/jibsen/tinf/tree/master/src

The most popular "header only" (or rather "single file" libs) are mostly written in C though:

https://github.com/nothings/stb

Important difference to typical C++ header-only libs: STB style libs don't use the inline keyword, but instead place the implementation into an ifdef/endif block.

It's really just for easier distribution and integration, and the difference to a single .h/.c pair isn't all that big.

Definitely not big enough to get all riled up about it - the actual problem are libraries that come in dozens of source and header files and with their own build system files, or C++ libraries which put the implementation into inline code, like most C++ stdlib headers (because this increases compilation time for every file which includes such a header).

There are many single-file C "libraries" that work perfectly fine as both "header" and "implementation", and that do not require unity builds (building everything as a single translation unit, e.g., a single .c file). Here is but one famous collection of them: https://github.com/nothings/stb
That’s not the case, if you take a bit of care. Look at STB for example (https://github.com/nothings/stb) -- I’ve successfully used STB functions on a bunch of different platforms. In both C and C++, even!
Even so, github does have a ton of very very popular C libraries(like https://github.com/nothings/stb). I was bringing up the OS provided ones since they claimed not to be able to find any. My main point is that it is patently absurd to claim that they could not find C libraries.

Further: https://github.com/oz123/awesome-c as another example of the many many C libraries you could find.

> Is this common practice? I’ve been assuming header files are used for unimplemented type definitions similar to TypeScript .d.ts files. Is this wildly wrong to assume?

By traditional reckoning, you’re almost correct, but this is an exception.

Unlike many other languages (including TypeScript AFAIK), C and C++ compilers are defined to process a self-contained piece of text (the “compilation unit”), which must declare the type of everything it uses from the outside; those are then linked together into an executable with external references bound by name, with the types blindly assumed to be correct. (The linker works at the assembly level, not the C level, the types are already gone.) The usual workaround is to have the preprocessor, which puts together said piece of text[1], pull in the declarations from a common source, the “headers”, just plain insert the declaration text into the source file. Thus the headers play a similar role to .d.ts files, but the toolchain does not impose any convention on how things are arranged in files, unlike in TypeScript, Go, or Java.

There are two downsides for this: first, the declarations go through the compiler once for every source file that uses them, yielding slower compiles; second, if you want to consume a library in source form you’ll have to marry the build system for the library with the build system for your consumer. (The “build system” is the conceptual thing that knows how to set up the header search paths, which files to compile, and how to link or otherwise package the results into build artifacts.)

An alternative to this traditional organization is the “header-only library”; it mostly eliminates the second downside at the cost of exacerbating the first.

- In the C++ world, the dumb linker model I described above is something of a lie: a lot of C++ things (vtables, inline functions, template instances, etc.) do not actually have a well-defined compilation unit they belong to (“vague linkage”), so in the simplest approach the compiler generates a definition for every compilation unit and the linker has to (know enough to be able to) throw away all of these except one. (You see where the notoriously long C++ compile times come from.) A header-only library then just bites the bullet, defines everything inline, and has the linker sort them out. These have become fairly common over the last decade. (This does not help the compile times.)

- In the C or C-ish-C++ gamedev world, there’s a practical need to get prototypes or good-enough preliminary versions out the door quickly, so the library that is easiest to integrate across as much build systems as possible has an advantage. A different variety of header-only libraries has gained traction there. These have the header contain both declarations and implementation, but the implementation is guarded by a preprocessor macro; the user of the library defines that macro in a single compilation unit that they designate as owning that implementation. (This has worse “tree-shaking” characteristics than a well-organized static library, but if the library isn’t large that’s probably not a big deal, and in any case many common libraries, such as libjpeg and libtiff, are not well organized in this sense.)

The QOI reference implementation comes from the second tradition and is probably influenced by the popular stb libraries[2].

[1] Actually a token stream.

[2] https://github.com/nothings/stb

I don't think file number / lines of code is a good measure, you can have perfectly readable code in a single file that is 1000s loc. There are plenty single header file libraries that are larger and are very useful. Perfect example is the stb libraries: https://github.com/nothings/stb very widely used in the C / C++ community.
This is a valid point. I was on the fence between doing .c/.h pair and a single .h. But finally took the inspiration from: https://github.com/nothings/stb.
That sounds like a fun challenge. If you're constraining yourself to use as few libraries as possible, I'd go with OBJ [1] for the 3d mesh and PPM [2] for writing images. It's easy to implement a bare bones reader/writer and some OSes (like macOS) can show them in the file browser. Raytracing in One Weekend goes over PPM. There are a bunch of header-only libraries that handle different file formats like stb_image [3]. I usually end up using those when I start dealing with textures or UI elements. I don't use Windows so I haven't used their APIs for projects like this. I'd usually go for imgui or SDL (like you mentioned). tinyracaster, a sibling project of tinyrenderer, touches on those [4]. I liked LazyFoo's SDL tutorial [5]. Good luck!

[1] https://en.wikipedia.org/wiki/Wavefront_.obj_file

[2] https://en.wikipedia.org/wiki/Netpbm#PPM_example

[3] https://github.com/nothings/stb

[4] https://github.com/ssloy/tinyraycaster/wiki/Part-4:-SDL

[5] https://lazyfoo.net/tutorials/SDL/index.php

Packing the entire library in a header file is a somewhat recent and much welcome trend.

See for example:

https://github.com/nothings/stb

https://github.com/nothings/single_file_libs

The language itself is a little unreadable at first glance, but the idea of it is a very good one. sbt [1] is an amazing project for small embeddable toy programs, but using fuzzers rapidly shows how unsafe the code is, and the benchmarks in the original article show the extent of performance compromises made to make it work.

It seems like this would be an interesting approach to a lot of security programming where it involves data structures, since those have typically been a source of issues. Having a memory-safe ASN.1 parser would be really nice, considering how much difficulty that has caused in the security space.

With a lot of security programming there's a reliance on constant-time algorithms, which this may not be well-suited to, however.

[1] https://github.com/nothings/stb

> I collect different C libraries as a personal stash of toolkits

Might you have a write-up or link for these, and if so might you be willing to share it?

I have been using Sean Barrett's libraries [0], as well as his curated list of other people's single-header libraries [1], and, like you, I am always on the lookout for new things to add to the collection :)

[0] https://github.com/nothings/stb

[1] https://github.com/nothings/single_file_libs

For me the best "package manager" are single header libraries like https://github.com/nothings/stb
Out of my personal go-to c++ libs, the only ones I missed are the stb libraries (https://github.com/nothings/stb/, in particular the image ones are very popular) and maybe ImGui, but that might be too niche.

Also I would love to have a nice c++ lib for uuids. It's in boost of course.. but well that's boost. Outside of that there is one, but it requires GSL.

It's not common, but there are other projects like this for easy integration, especially on embedded systems. You see some C++ libraries that are a single header file include. And here is a collection of single file headers for graphics tasks, like loading images, resizing images, rendering font glyphs, etc:

https://github.com/nothings/stb

The author's opinion is uncommon but not unique.

A few examples: https://handmadehero.org/ https://ourmachinery.com/post/physical-design/

Simple libs widely used in game dev circles: https://github.com/nothings/stb

This one is a full game engine with tools made for educational purpose: https://www.raylib.com/

I do write games and game engine code and tools in C++ without using any of the OOP features.

I know quite a few of other professional, experienced and talented developers doing the same, even full AA studios with up to 50 employees.

Some of them are going back to procedural C after a few years of disappointment with OOP madness.

I'll publish articles about this later, but for now, all I have to say is that it just works.

Newbies are often afraid of manual memory management and pointers, but there are simple ways to avoid shooting yourself in the feet with those.

https://github.com/nothings/stb is another set of good header only libraries.

(I'm not the author and don't know them, I'm just a happy user.)

Proper "stb-style" header-only libs split the header into 2 parts: the declaration part that's always included and parsed but only contains the public API declarations, and the implementation part inside an #ifdef XXX_IMPLEMENTATION section which is only included and parsed in a single source file.

The same idea can also be used for C++ headers (unless it's all template interfaces).

With such stb-style headers, you can even get better compile times, because you can include all header-libs into a single implementation source file, giving the same advantages as unity-builds (merging all sources into one file).

PS: origin of the name "stb-style": https://github.com/nothings/stb (although I guess the general idea existed before)

One thing that I like about Lua over Javascript is how self-documenting, fun to write, and easy to read it is. It has a very simple syntax, but the extensibility of its core structures (like tables) let you accomplish a lot with that simplicity.

Its 3rd-party libraries also tend to be closer to C/C++'s "drop-in" solutions like STB[1] than the enormous JS ecosystem which often requires extra tools like Node and/or extra packages like JQuery.

Admittedly, Lua's ecosystem is much smaller than Javascript's, but in my experience Lua is vastly easier to maintain. You can certainly write bad Lua, but it's one of the only languages where I don't implicitly dread reading other people's code.

It is sort of annoying that tables which are treated like arrays are 1-indexed by convention, though.

[1]: https://github.com/nothings/stb

For C vectors, look at stb's[1] stretchy_buffer[2] or klib's[3] kvec[4].

The basic concept of these is they use macros to specify the type/size of the elements so you can have generic containers in C.

For hash's, you can also look at klib's khash [5]

[1] https://github.com/nothings/stb

[2] https://github.com/attractivechaos/klib

[3] https://github.com/nothings/stb/blob/master/stretchy_buffer....

[4] https://github.com/attractivechaos/klib/blob/master/kvec.h

[5] http://attractivechaos.github.io/klib/#Khash%3A%20generic%20...

Sean Barrett (who I think popularized the idea) has a FAQ on this (https://github.com/nothings/stb) where he justifies it by pointing at difficulties with deploying libraries on Windows. Which is a fair point, but by going straight to header-only he skips the step where you can also just distribute a bunch of headers and .C files. The convenience of only having to include a single header is nice for quick weekend projects, but for anything bigger you're dealing with dependencies and build issues anyway.

I get some of the reasons that you would initially start out with a header-only implementation, but when your library grows, you probably want to split it at some point. For me personally, that point would be some time before the header reached 25k (!!) lines.

If you need a minimalist open-source font rendering library, look at stb_truetype: https://github.com/nothings/stb A single header file. Unfortunately it cannot do what harfbuzz or pango do, that is lay out complex scripts or do any layout
Also there is the header-only khash.h [3], complete with benchmarks:

https://attractivechaos.wordpress.com/2008/08/28/comparison-...

(Also provides kbtree.h, ksort.h, kstream.h, kvec.h)

[3] https://attractivechaos.wordpress.com/programs/

Also there are the stb header-only libraries. There is a hash table implementation buried inside stb.h

[4] https://github.com/nothings/stb

Increasingly popular are the "single header libraries", which were popularised by Sean Barrett[0]. It's as simple as downloading the header, putting it somewhere in your tree and #including it where you need it. It's especially useful for redistributing libraries, but I've also found it useful to create these in my own projects.

[0]https://github.com/nothings/stb

There's another set of similar libraries called the STB Libraries, primarily aimed at gamedev/graphicsdev: https://github.com/nothings/stb
I was (pleasantly) surprised to find out Fossil used a Tcl-like language for templating.

Tiny Tcl implementations are fun in general and perhaps easier to produce than tiny Scheme implementations — as long as you are willing to concede that everything really is a string. :-) (I.e., no caching binary representations; you have to parse from scratch each time.) In a similar vein as TH1 but with a little more functionality there are Picol (https://tcl.wiki/Picol) and LIL (http://runtimeterror.com/tech/lil/).

Disclosure: I maintain an expanded fork of Picol. The original version of it written by antirez was only ~550 LOC but with suchenwi's additions and mine it is now around 3100. There is a link to it on the wiki page. The change that I am most fond of is making it an stb-style (https://github.com/nothings/stb/) header library.

One practical example would be tigr [1] - a cross platform window framework for making simple applications, could be compiled as one header drop-in only lib. You simply cannot make it one header without making calling ObjC runtime from C. Why it's necessary to make it work as one drop-in header? Well it's a new trend in C libraries, which allows using libraries with the least resistance possible, it's like a package manager but nicer - you only have one file! Great example of modern one header libs is probably the famous stb package [2].

- [1] https://bitbucket.org/rmitton/tigr/src

- [2] https://github.com/nothings/stb

"What about unit-testing framework and some best practices?"

A random collection of anecdotal stuff and opinions that comes to my head:

For common utilities for game development stb libraries are fantastic: https://github.com/nothings/stb

For general idea how to structure code you could google "data oriented design c++".

Try not to structure your solution around class hierarchies but prefer data pipelines.

Write your code so that it's easy to debug.

Prefer to structure your solutions around stl containers and stl algorithms.

Avoid using inheritance as long as it does not reduce code complexity. If you use inheritance prefer to use only abstract base classes. Do not use template metaprogramming unless you are absolutely sure it's the most simple way to solve your problem. Avoid multiple inheritance like the plague. Ignore my advice if your problem is such that they don't make sense.

Try not to solve any other problem than the one you have immediately in front of you, and solve it as fast and simply as possible. Do not try to create some "framework" to solve your problems but prefer simple code. Refactor your code as your program progresses. This point might be obvious - but for me personally has been the most difficult thing to learn - writing agressively simple code is the best thing I've learned. This does not mean that the abstractions that are implemented are necessarily simple - just that the implementation is as easy to read, easy to debug and easy to reason about it's dependencies, as possible.

If you can trade off complexity of dependency with a little bit more code, prefer little bit more code. I.e. if you have an itch to include a library because you need a single function, think hard about implementing or copy pasting the function to your codebase. Once you are confident enough that you know you need something, only then include it.

Learn some OCaml :) - really, I feel like much better C++ programmer after I understood how a properly designed language with a static type system works. (I hear "Real world OCaml" is a good book).

Uh, this stb library [1] seems to follow a horrible pattern: not only combining your code into a single .c file (which is fine, like the sqlite amalgamation), but putting the code into a single .h file. [2]

I've never seen a C or C++ codebase that does this. Maybe you can rely on link-time deduplication, but it will still cause duplicate compilation, and thus increased compile times. I haven't thought it about it lately, but I thought the common wisdom was not to depend on the linker to dedupe or strip unused symbols. Actually it should cause link-time errors, not just duplicated cause.

The justification is also somewhat ridiculous: Why single-file headers?

Windows doesn't have standard directories where libraries live. That makes deploying libraries in Windows a lot more painful than open source developers on Unix-derivates generally realize. (It also makes library dependencies a lot worse in Windows.)

Really? Why not just lay out your source normally, and then munge it with a simple script into something Windows can handle (similar to sqlite)? Because writing trivial scripts on Windows is also a pain?

[1] https://github.com/nothings/stb

[2] https://github.com/nothings/stb/blob/master/stb_c_lexer.h

From the popular (in game development circles, at least) stb libraries:

>Why single-file headers?

>Windows doesn't have standard directories where libraries live. That makes deploying libraries in Windows a lot more painful than open source developers on Unix-derivates generally realize. (It also makes library dependencies a lot worse in Windows.)

>There's also a common problem in Windows where a library was built against a different version of the runtime library, which causes link conflicts and confusion. Shipping the libs as headers means you normally just compile them straight into your project without making libraries, thus sidestepping that problem.

>Making them a single file makes it very easy to just drop them into a project that needs them. (Of course you can still put them in a proper shared library tree if you want.)

>Why not two files, one a header and one an implementation? The difference between 10 files and 9 files is not a big deal, but the difference between 2 files and 1 file is a big deal. You don't need to zip or tar the files up, you don't have to remember to attach two files, etc.

https://github.com/nothings/stb/

Unfortunately, Opus doesn't have a proper specification, instead relying on source code in several places to provide documentation through extrapolating what code intended.

To quote Sean Barrett:

  Opus' non-public-domain code as spec is terrible.\n  Independent implementation requires "clean room" = writing\n  own specification!\n
\nSean is famous among the game developer community for providing a useful variety of public domain code (i'd call them libraries, but almost all are written to be used as a single-header file include):

https://github.com/nothings/stb

What other APIs would that be which offer this functionality? In D3D this used to be offloaded into a separate D3DX API, but AFAIK this is no longer supported in Windows8 (at least in the WinRT API) and has been moved into separate mostly personal projects (e.g. http://directxtex.codeplex.com/). A 3D rendering API should only be concerned about efficient 3D rendering and not burden itself with specific resource file formats. For OpenGL there's plenty of libraries to choose from, for instance:

- glm for math (http://glm.g-truc.net/0.9.5/index.html)

- gli for texture loading (http://gli.g-truc.net/0.5.1/index.html)

- assimp for general asset loading: http://assimp.sourceforge.net/index.html

- the STB headers (not OpenGL specific): https://github.com/nothings/stb

- GLFW as window system glue and input wrapper

- ...and more which I am not aware of or forgot to list

GPU vendors also have SDKs and especially debugging tools (e.g. NVIDIA nSight which integrates into VStudio). It's not in one place like in DirectX, but on the other hand, the OpenGL world has a lot more platforms and usage scenarios to cover then D3D or the various new-style APIs like Metal or Mantle (these are the actual motivation for OpenGL-Next, reducing overhead even when this means a lower-level API which is even more focuses and harder to use then before).