5 ms·
None of the functions seem to be marked static or inline. Isn't this an instant link error once you include the same header in two different translation units?
by leni536 4y ago
None of the functions seem to be marked static or inline. Isn't this an instant link error once you include the same header in two different translation units?
- wruza 4y agoSeems like there’s #ifdef _CLIB_IMPL to control that, but I’m still missing the point.
- pjmlp 4y agoThe point is unwillingness to learn how to work with compiler toolchains and package repos, while imposing longer compile times on everyone.
- foldr 4y agoCould you show an example of how you'd package this code?
- linkdd 4y agohttps://github.com/ocornut/imgui https://github.com/ocornut/imgui > Just copy paste the source code in your source tree And/Or make a simple CMakeLists.txt like this: cmake_minimum_required(VERSION 3.22.0) project(mylib C) file(GLOB_RECURSE MYLIB_SOURCES ${PROJECT_SOURCE_DIR}/src/*.c ) file(GLOB_RECURSE MYLIB_HEADERS ${PROJECT_SOURCE_DIR}/include/*.h ) add_library(${PROJECT_NAME} STATIC ${MYLIB_HEADERS} ${MYLIB_SOURCES}) target_include_directories(${PROJECT_NAME} PRIVATE "${PROJECT_SOURCE_DIR}/include" )
- foldr 4y agoThat's not really any different from how this library works. CLib just chooses to avoid the necessity of adding additional makefile definitions at the cost of making the preprocessor fast-forward through a bit more text. As it's a small amount of text anyway, I doubt it makes much difference. (The implementation code only gets parsed once, even though it's scanned multiple times by the preprocessor.) It seems a bit unfair to assume that the author has an "unwillingness to learn how to work with compiler toolchains and package repos" just because they chose to make this tradeoff. Also, OP referred to 'package repos', which obviously aren't involved in your example.
- linkdd 4y agoIf the library was instead giving me a .c and a .h, I would simply need to make that CMakeLists.txt, or a Makefile, or whatever build system I use. Now, the library gives me a .h and a `#define XXX_IMPL`. So to avoid making the mistake of defining XXX_IMPL more than once, I'll have to make a .c myself for each file of the library, and then I still need to write the CMakeLists.txt/Makefile/whatever. This is just wasting my time for no good reasons. I linked the imgui repository because that's what they do, they give you the .c/.h and you decide how to build it. You just have to copy/paste, no time wasted.
- foldr 4y ago>So to avoid making the mistake of defining XXX_IMPL more than once, I'll have to make a .c myself for each file of the library Hmm, I guess I wouldn’t worry about that and I’d just define XXX_IMPL in one of the existing .c files that imports the library. If I make a mistake and define it in multiple .c files then I’ll get an easy-to-interpret compiler error and it will be easy to fix the mistake. I imagine that’s how the author envisions the library being used. But yeah, if you don’t want to do it that way for some reason, then there’s no particular advantage to this style. I’m not sure that I hate it any more than I hate every other hack for distributing C libraries in the absence of a proper module system.
- flohofwoe 4y agoUsing file globbing isn't exactly 'best practice' for CMakeLists.txt files though ;) (and while Dear ImGui is definitely manageable, you still need to decide what to include in your project, for instance: why add imgui_demo.cpp)
- pjmlp 4y agoJust like any classic C library with a static and dynamic versions, using pkg-config to get the respective build flags. If targeting only Linux workloads, use something like checkinstall to generate all lib-xyz-dev flavours. If targeting cross platform, settle on one of conan, vcpkg or cmake packages.
- torstenvl 4y ago> Just like any classic C library ... using pkg-config A "classic C library" cannot assume the existence of pkg-config (or checkinstall, or conan, or vcpkg, or cmake). It can assume the existence of the preprocessor.
- pjmlp 4y agoRead the rest of the comment... EDIT: Since you modified the comment, it can at very least assume the existence of a compiler, a linker and make.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- torstenvl 4y agoNo, it really can't. Nothing about C guarantees that the implementation will provide `make` (let alone that it will be POSIX make or BSD make or GNU make). Nor (going back to your original comment: https://news.ycombinator.com/item?id=34244452 https://news.ycombinator.com/item?id=34244452) is it guaranteed to be hosted on a system with dynamic linking. The OP library has a design such that the only build system you need is the preprocessor. That is a perfectly valid design decision, especially since this is explicitly for lighter-weight uses where GLib would be excessive. If you don't like it, don't use it. EDIT: Clang, for example, does not provide a `make` or guarantee a `make` exists. It will happily co-exist with BSD make on FreeBSD, or GNU make on macOS, or no make at all. I assume you concede on pkg-config, etc.
- flohofwoe 4y agoOh come on, stop with the FUD :) Unlike typical C++ "header only" libraries, the compilation time increase for STB-style "single-file libraries" is completely negligible because the implementation is also just compiled once for the entire project. Skipping an ifdef-block happens at IO speed, and this is very fast (at least since we left floppy disks behind). We also don't advice people to not comment their code (skipping ifdef is about as fast as skipping comments), or use one-character variable and function names to speed up compilation ;)
- pjmlp 4y agoBack in 1999, I used to wait 1h for building our CRM server solution from scratch, written in a mix of C and TCL, while taking advantage of ClearMake optimization to share object files across the build machines. So nope, no FUD, rather production deployment experience. Naturally if one plans to use C as a scripting language, in tiny projects, maybe it doesn't matter.
- hmry 4y agoYou only #define _CLIB_IMPL 1 in one translation unit when compiling.
- leni536 4y agoAh, OK. I was confused how that was supposedly used. I suppose header-only C libs are somewhat a pain, as inline does not work the same way as in C++, and static may cause code bloat when inlining does not happen in multiple TUs.
- linkdd 4y agoC Header-only libraries do not exist. It's just `#include "foo.c"` with extra steps.
- badsectoracula 4y ago`#include "foo.c"` would repeat the implementation in multiple object files which is both wasteful and, if not using static, create conflicting symbols.
- linkdd 4y agoYou missed the "with extra steps". #define XXX_IMPL #include "xxx.h" And #include "xxx.c" Are exactly the same trash.
- badsectoracula 4y agoNo they are not, the former allows you to include the header file in multiple .c files, the latter does not.
- foldr 4y agoStatic is probably safer in C (as opposed to C++), as it's valid to have a function with the same name defined as inline within one translation unit and elsewhere with external linkage. The compiler is then free to resolve the relevant function calls to either the inline version or the external version (!) https://www.ibm.com/docs/en/ssw_ibm_i_73/rzarg/inline_linkage.htm https://www.ibm.com/docs/en/ssw_ibm_i_73/rzarg/inline_linkag...