6 ms·
Because C has no package system and it sucks, and having a single file (ideally with no dependencies, which isn't the case here) makes it super easy to integrat
by simias 8y ago
Because C has no package system and it sucks, and having a single file (ideally with no dependencies, which isn't the case here) makes it super easy to integrate it anywhere.
A good example of that IMO is cJSON[1], it's a small self-contained single file implementation of a JSON reader and parser. It's easy to use, the code is pretty clean and easy to follow and I never ran into any obvious limitation. I very much recommend it.
There are also projects that are developed as multiple files but amalgamated into a single huge file before release. SQLite does that: https://sqlite.org/amalgamation.html https://sqlite.org/amalgamation.html
> Over 100 separate source files are concatenated into a single large files of C-code named "sqlite3.c" and called "the amalgamation". The amalgamation contains everything an application needs to embed SQLite. The amalgamation file is more than 220,000 lines long and over 7.5 megabytes in size (as of 2018-11-24).
> Combining all the code for SQLite into one big file makes SQLite easier to deploy — there is just one file to keep track of. And because all code is in a single translation unit, compilers can do better inter-procedure optimization resulting in machine code that is between 5% and 10% faster.
[1] https://github.com/DaveGamble/cJSON https://github.com/DaveGamble/cJSON
- peterwwillis 8y agogcc -shared -o mycrypto.1.1.so file1.c file2.c file3.c file4.c #include "mycrypto.1.1.h" Doesn't that have the same effect of being easy to include? The amalgamation may be better for the compiler but I'm not sure why.
- tialaramex 8y agoA platform has a fixed ABI that says e.g. the first integer parameter to a function goes in register R14, the sixth one goes on the stack. If you have sixty C files the compiler is obliged to produce sixty object files which each obey that ABI for all their functions because you might stitch in some other code, not using that compiler at all, which obeys the ABI and if you ignore the rules this will unexpectedly not work. But within a single object the compiler doesn't need to obey the ABI rule at all if that's faster. Now, you obviously could imagine an object and more powerful linkers that had enough optimisation magic to produce the same output executable from the sixty object files, but just spitting out a single source code file is a LOT easier than making that optimisation work on every platform now and in the future.
- tedunangst 8y agoThe compiler invocation above only creates a single object file.
- tialaramex 8y agoNo, but I can see why you thought so. The invocation above creates one object file for each C source file, as temporary files, (in a Unix system you can watch it do this with a suitably powerful syscall tracer, presumably something similar is possible on non-Unix systems but I don't know exactly how) Then it links them and produces the output you've mistaken for an "object file", then it deletes the temporary files.
- tedunangst 8y agoAh, probably the easiest way to deal with some translation unit edge cases. :(
- CJefferson 8y agoNow do it on Mac, and windows, and dynamic and static, and install the libraries in the right place. It gets maddening.
- gray_-_wolf 8y ago> compilers can do better inter-procedure optimization resulting in machine code that is between 5% and 10% faster. does this hold even when non-amalgated code uses `-flto` or equivalent flag?
- simias 8y agoI don't know what's the state of the art for link time optimization these days but I would assume that it's still somewhat more limited than compile-time optimization. You can usually be a lot more aggressive when you have the full context of the code being optimized.
- jedisct1 8y agoTossing everything into a single file is not required. You can use includes to have "a single file to add to the project", and still split your code in smaller, readable files. See https://github.com/jedisct1/libhydrogen https://github.com/jedisct1/libhydrogen for example. It's a single-file crypto library from an application perspective, but everything was not stored into a single, hard-to-navigate file.