4 ms·
It pains me to see #include <olive.c> at the top of the file. It makes the project feel like a toy.
by jandrese 4y ago
It pains me to see #include <olive.c> at the top of the file. It makes the project feel like a toy.
- KMnO4 4y agoJust wait till you find out that you can do: const char *s = #include "test.txt" ;
- unwind 4y agoSure, but only if the text file looks like a C string literal, i.e. starts and ends with double quotes (which would make it into a weird text file). Doing const char *s = " #inclued "test.txt" "; won't work, since the preprocessor won't interpret directives inside string literals of course. In many assemblers, there is a directive called "incbin" which pastes in unstructured binary data at the point of usage. I just found a very clever C and C++ wrapper [1] for that, which gives you an INCBIN() macro. Nice! [1]: https://github.com/graphitemaster/incbin https://github.com/graphitemaster/incbin
- cygx 4y agoNote that C23 will include a variant of incbin spelled #embed: Semantically, the preprocessor will insert a list of integers which you can use to initialize an array.
- jsmith45 4y agoAlso, for clarity, it is fully expected that the compiler will use the as-if rule to optimize it. Most likely by having a dedicated token/ast node that only decomposes to comma separated values if if actually needs to, with common usage in initalizers being handled by simply copying the data directly into a static data segment without ever creating an integer list at all.
- a_e_k 4y agoAn incbin-like facility is coming to the standard: https://thephd.dev/finally-embed-in-c23 https://thephd.dev/finally-embed-in-c23
- unwind 4y agoYeah, I actually had heard about that but it didn't show up in my first search. Thanks!
- iforgotpassword 4y agoYeah, ignoring incbin hackery, a better example than strings might be float vertices[] = { #include "stuff.txt" };
- mcmuffin6o 4y agoSorry, why does it make the project feel like a toy? I'm not trying to argue, I just don't understand. Is it because you're including a source file instead of a header file?
- teraflop 4y agoThe function declarations and definitions are all commingled in a single file. So if you want to use this library in a project that contains multiple source files, you have to include a duplicate copy of the implementation (including e.g. the static font data) in every single compilation unit. It's possible that your linker would be smart enough to identify and remove the duplicates, but it's still inelegant, unidiomatic and needlessly inefficient.
- jandrese 4y agogcc or clang would crash on the linking step complaining about duplicate symbols. This library is only good for a project that is built in a single .c file.
- anthk 4y agoFalse.
- esrauch 4y agoThat's not true in this case: if you look at the .c file you can see it actually has no definitions by default and is a relatively normal .h file when it's included. You can #include it in any number of files as long as exactly one has #define OLIVEC_IMPLEMENTATION.
- dundarious 4y agoThere 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 https://github.com/nothings/stb
- kazinator 4y agoIt looks like olive.c is a "single header" library. They chose a .c suffix rather than .h. If OLIVE_IMPLEMENTATION is defined before including "olive.c", then the full implementation is produced. Otherwise, just declarations, so that it behaves like a header file. It's a valid technique. If you have a library all in one source file, the requirement to have a separate .h doubles your file count. One small reason to have a .c suffix is might be that your editor can then choose a more specific syntax scheme. A .h file could be C++. Another one is that it can be used as a source file. You can pop it into a Makefile project, and just make sure you have -DOLIVE_IMPLEMENTATION on the compiler command line for that file. Other files using it just include "olive.c" to get the declarations. Because it has a .c suffix, make will handle it via its .c.o rule.
- jandrese 4y agoThis feels far messier to me than just having a .h file.
- worthless-trash 4y agoIts part of the spec, and not even obscure. this is not even scratching the surface of nightmare level C.
- kazinator 4y agoSure, but let's look at the larger picture. If you have one file, then that's your deliverable. You can host that file somewhere, send it as an e-mail body, drop it into a paste-bin or whatever. It is one self-contained unit. If you have two files: .h and .c, the use scenario may be simpler. Not a lot though. And now youu have two files which have to stay together somehow, yet remain distinct. If you combine them in one body of text, you have to indicate: oh, please snip out this part as a .h file and then the rest as a .c file. In e-mail you can have it as two separate MIME attachments. You can use an archive file --- have you looked into the formats? Not so simple. It's not hard to understand the attraction to the one file deployment, even if you don't do it yourself.
- 4y ago
- LastTrain 4y agoThen you made an incorrect assumption without enough investigation.