Remix.run Logo
uecker 3 days ago

I like simple code written in C, but when does this "single-header" nonsense stop? C has super nice and simple modularization via the classical .h/.c split which ensures fast compilation, proper encapsulation, no instruction bloat via creating multiple instances for all functions.

colleagueRiley 3 days ago | parent | next [-]

Try putting GLFW's source code into one file and then compile it. That will take at least a few seconds, RGFW compiles in less than a second.

Where's the bloat? :)

https://github.com/SasLuca/glfw-single-header/blob/master/ex...

uecker 3 days ago | parent [-]

The issue if if you have many such libraries and any change to the implementation forces recompilation of everything. Maybe not such a big deal for such small libraries, but an annoying trend IMHO.

tredre3 3 days ago | parent | prev | next [-]

> no instruction bloat via creating multiple instances for all functions.

This makes me think that you're using single-header libraries wrong. These kind of libraries usually require you to do something special prior to including it to get the actual code and you must do it only in ONE file.

For example, you'd #define RGFW_IMPLEMENTATION before #include rgfw.h in exactly ONE .c. If you need the header in other files, you do NOT define RGFW_IMPLEMENTATION and no code will be produced.

uecker 3 days ago | parent [-]

Well, I do not use them at all. But I agree that this mechanism would avoid the additional copies. I have seen other single-header libraries though...

In any case, forcing me to figure out the specific XYZ_IMPLEMENTATION for each library is less user friendly that just proving a .c and .h file.

tredre3 2 days ago | parent | next [-]

I actually agree with you that single-header libs are often not ideal. They're kind of neat in concept: just copy paste and done!

But after being burned a few times by naming or linking conflicts or you cloned your .c and forgot to remove the #define and now you have two implementations or having to debug any BSS/DATA/TEXT issues (because now lib and user code end up in the same .o and the linker can't do its magic for your esoteric architecture), I just took the habit of always manually creating a matching .c that only contains:

    #define BLAH_IMPLEMENTATION
    #include "blah.h"
colleagueRiley 2 days ago | parent | prev [-]

Well for one you're able to easily use macros to customize features you want and don't want. Plus "forcing me to figure out the specific XYZ_IMPLEMENTATION" is a big of a weird compliant. You could say the same thing about linking a library. Besides, it's not hard to figure out and is usually one of the first lines of the file.

The single-header format also gives you MORE ways to compile the library and control which features to use or not use.

uecker 2 days ago | parent [-]

I am not say it is hard. But I find having a .c/.h pair more useful and easier to work with.

colleagueRiley 2 days ago | parent [-]

No lol

uecker 2 days ago | parent [-]

Because looking up a macro name for each library is easier than adding a c file to your makefile? You could still always do

  #include "impl.c"
and this would still be nicer than

  #define XZUGG_IMPL
  #include "impl.h"
CyberDildonics 3 days ago | parent | prev | next [-]

I can't figure out why anyone would call it 'nonsense'. The definitions and functions have to be together, they may as well be a single file separated by a preprocessor definition.

Include the header where you want the definitions. Include the header and use the preproccesor definition in the compilation unit you want the functions in. Done.

There is no speed issue here. It would take 100x the C to make a difference and it's actually going to be much faster and simpler to put a lot of single file libraries into one compilation unit. I always wonder if the downsides are theoretical or if people are really doing what I've been doing and still have a problem with it.

pjmlp 2 days ago | parent | prev [-]

Too many script kiddies taking C for another scripting language.