7 ms·
I just recently started learning c and having hard time wrapping my head around third party libraries. Coming from Node/npm I’m used to the idea that your depe
by jalino23 4y ago
I just recently started learning c and having hard time wrapping my head around third party libraries.
Coming from Node/npm I’m used to the idea that your dependencies gets bundled in your app. But its not like that on C.
you expect your users to install your app dependencies for you, and you have to figure out the path of your own dependencies.
cause they don’t live in one nice place like node_modules. and I haven’t even began to figure out how Im supposed to know what linker flag to use for the library I use.
the tutorials just give it to you without explaining where they get it from.
and most of the sources I’ve read almost always recommends dynamic linking cause static is heavy. which brings me back to this article that now recommends static linking and I agree with that.
much of the learning materials I’ve come across are just spoon fed to you without explaining why. And its so incredibly frustrating until you look at linux history, most of the assume knowledge now is based on baggage upon baggage of layers of history.
- zabzonk 4y agolearn c++ instead - despite what you may have heard, it is much easier to learn than c. but neither language (and they are very different) has standardised library/package tools.
- MattPalmer1086 4y agoI don't think this is good advice, although I don't agree with you being downvoted because of that. C++ is a much more complex language than C. The things you need to worry about in C are far fewer than in C++.
- zabzonk 4y agook. a small challenge - read character input of undefined length, and then print the input out backwards. i guarantee the c++ code will be easier to write and understand than any c code.
- camel-cdr 4y agoThat actually sounds like a fun way to explore different programming languages. Especially if you extend it to inputs that may take up more memory then you've got on your computer (let's say 100GB) and at least reasonably fast. I suppose it'd kinda trivial if you read the input from a regular (seekable) file, but if you actually read the 100 GB from stdin then this could get quite complex.
- zabzonk 4y agofinding good teaching examples is hard - here's one i prepared earlier https://latedev.wordpress.com/2011/07/28/writing-a-real-c-program-part-1a/ https://latedev.wordpress.com/2011/07/28/writing-a-real-c-pr... but could not complete as i was struck down with terrible depression, and then my mum & dad needed looking after, and then...... perhaps i will start it up again, now it is just me, and not exactly happy, but not depressed.
- johndough 4y ago> i guarantee the c++ code will be easier to write and understand than any c code. That will depend on how you define "understand". For a superficial level of understanding, you might be right. But the C++ code will make use of many concepts that would take a while to explain, for example references, classes, inheritance, templates, operator overloading, STL, and probably a bunch of other things I forgot.
- erik_seaberg 4y agoThere are books explaining those things, and as a professional I can expect to amortize the effort over years of other projects.
- wizzwizz4 4y ago#include <stdio.h> #include <stdlib.h> int main() { size_t len = 0, cap = 0; char *buffer = NULL; int c; while ((c = getchar()) != EOF) { if (len >= cap) { cap = (cap << 1) + 1; { char *newbuf = realloc(buffer, cap); if (!newbuf) { fprintf(stderr, "Could not reallocate to %zu. Printing what I've got.", cap); break; } buffer = newbuf; } } buffer[len++] = (char)c; } while (len --> 0) { if (putchar(buffer[len]) == EOF) { fprintf(stderr, "Output failure."); return 1; } } free(buffer); return 0; } Most of the verbosity here is in correctly handling errors, something that isn't much easier to do in C++. (Be warned: I haven't tested this code.)
- blackpill0w 4y ago>C++ is a much more complex language than C While this might be true, generic containers, sane strings, RAII and the possibility of not having to deal with pointers makes C++ an easier language to work with. You certainly need to worry about much less things long as performance is not a priority.
- bsder 4y ago> sane strings So, explain to me why every C++ program always has its own String implementation? > long as performance is not a priority. Then C++ is a disastrous choice. Almost anything is better.
- zabzonk 4y ago>So, explain to me why every C++ program always has its own String implementation? i have no idea where you are reading about c++, but every c++ program i have read or written in the past 20 years or so does #include <string> std::string greet = "hello, world"; the full-stop in front of the hash is something with HN, not me or c++, and only seems to show up when editing.
- blackpill0w 4y ago>So, explain to me why every C++ program always has its own String implementation? *saner :) >Then C++ is a disastrous choice. Almost anything is better. True, C and C++ are most of the time not the right tool for the job nowadays. But, if it's just a project that you're working on in your free time, it wouldn't harm to write it in your favorite language. I write in C++ a lot even if I could do the same thing much easier in other languages.
- wizofaus 4y agoThe last sentence doesn't really follow from the previous one. C++, like other higher level languages, has complexity built in because it takes care of things that in C you have to take care of yourself. I can't imagine any serious C++ project becoming "less complex" to work on by rewriting it in C.
- uecker 4y agoI personally found it very relieving when I switched from C++ to C. (and I also rewrote some stuff, it did not get more complex.) I find readability of modern C code much better than C++. In C you see what you get: no templates, overloading, virtual inheritance, namespaces, exceptions, references etc you need to keep processing in your head just to understand what is going on.
- wizofaus 4y agoI don't doubt that can be true - but there are plenty of common operations like concatenating strings or converting between strings/numbers that are a good deal simpler to write and understand in C++ than they are in C. In particular there are far more ways to get them wrong in C!
- uecker 4y agoIf you code them by hand, then yes. If you a library, then it is the same. It is certainly true that the C++ standard library provides more functionality out of the box.
- wizofaus 4y agoAlmost any C library function that deals with strings is going to be more complex to use due to the lack of automatic memory handling, necessary for any use case where the max. size isn't sufficiently well-known at compile time for it to sit on the stack. I'd accept something like "atoi" or "strtol" is pretty simple to use (and hard to get wrong), but hardly win any awards for obviousness. And the less said about the need (or at least strong tendency) to use sscanf for more complex parsing (hexadecimals etc.), the better.
- WalterBright 4y agoYou can learn C in a few days. It takes 10 years to learn C++. My experience, anyway.
- zabzonk 4y agoi respect your opinion, but for example you can do some very common tasks using std::string that will be really difficult in c. and much of programming is dealing with strings. speaking as a c and c++ trainer here.
- cozzyd 4y agoThe lazy way to do things with strings in C is almost always asprintf
- bitwize 4y agoMy experience is you can get to where you think you know C in a few days. But it may take decades to become aware of all its footguns, and much more time to learn how to program C in a way that avoids them -- if that can be done by humans at all. (Maybe our new AI overlords will figure it out.) Nuke the site from orbit. It's the only way to be sure. Deprecate C for all greenfield development, and launch a big-science push to rewrite all the extant load-bearing C code in something else with safety guarantees (Rust=good, SPARK=better). If null pointers were a billion dollar mistake, then letting C become ubiquitous was a mistake that runs in the trillions.
- elteto 4y agoIf this was even remotely true we wouldn’t be living in a world full of kernel exploits and broken software, with a lot of it written in C. Writing C code is hard.
- WalterBright 4y ago> Writing C code is hard I found it very easy. I was writing production C code in a few days. (Of course, I was an experienced asm programmer before that, and C was a natural.) I write code very differently today. But that's not learning C, it's learning technique.
- enriquto 4y ago> you expect your users to install your app dependencies for you Yes, you do. And that is a good thing. > and you have to figure out the path of your own dependencies. No, you don't. Once a build dependency is installed, the compiler and the linker find it automatically. All of this is easier than it sounds. For example, say your program depends on libpng. Then your users will have to "apt get install libpng" (or whatever your distro does). Then on your C files you just write #include <png.h>, on the call to the linker you will have -lpng and everything will work correctly. The C ecosystem does not favor dependencies whose api changes every month, so this will work with whatever version of the libraries you have. Of course, you are also free to bundle all the dependencies that you want with your code. And you can easily distribute static executables that will work everywhere.
- VWWHFSfQ 4y ago> No, you don't. Once a build dependency is installed, the compiler and the linker find it automatically. Except when they don't. And you're left to figure out the right incantation of linker flags to use. Maybe give up and start symlinking stuff around until it works.
- db48x 4y agoCompiler and linker flags are so annoying that people built tools to make developers lives easier. They aren’t amazing tools, but they get the job done. In this case, you would run `pkg-config -cflags libfoo` and `pkg-config -libs libfoo` and use the results when you invoke the compiler and linker.
- enriquto 4y ago> Compiler and linker flags are so annoying (...) Hmmm. I'd rather say that some people who package libraries are very annoying! If a library needs specific compiler flags, or linker flags beyond "-lfoo", this means that somebody is doing something wrong. Out of incompetence or out of malice.
- 4y ago
- rwmj 4y agoIt works in conjunction with your distribution package manager, so in Fedora I install the dependencies I need using 'dnf install foo-devel' or if the program is already known to Fedora I can install all the dependencies with 'dnf builddep program'
- woodruffw 4y agoLinux and other Unix-likes have a standard for this: if you want to link against libfoo, you pass `-lfoo`. The standard linker knows to expand that to some variant of libfoo, whether static or dynamic, with additional versioning, etc. If libfoo isn't in a standard library search path (e.g. it's being built in a `./vendor/` directory), then you need to additionally tell the linker that with `-Lvendor -lfoo`. There's also a lot of silly memorization involved (e.g. remembering that zlib is usually packaged as `libz` so you need `-lz`, remembering that the non-SSL parts of OpenSSL are `-lcrypto`, etc.). C programmers tend to build mental scar tissue around these things and forget how pointlessly complicated and friction-inducing they are.
- rattlesnakedave 4y agoYes, this is crap, and not useful on modern systems. The only reason many claim to not think so is because they’ve been forced to figure it out, and now want others to as well.
- JCWasmx86 4y agoYou can use pkg-config for that. E.g. if you want to compile with glib-2.0, you can run `pkg-config --cflags glib-2.0`: -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-4 -pthread (E.g. for compiling to object code, but not linking yet) Add `--libs` to link against it, too: -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -I/usr/include/sysprof-4 -pthread -lglib-2.0 With meson that is basically `dependency('glib-2.0')` that you add to your executable/library. > you expect your users to install your app dependencies for you, and you have to figure out the path of your own dependencies. If you use a good buildsystem, it will find those dependencies automagically or you can e.g. use wrap dependencies: https://mesonbuild.com/Wrap-dependency-system-manual.html https://mesonbuild.com/Wrap-dependency-system-manual.html Those do automatically download the dependencies and compile them for you
- johndough 4y ago> You can use pkg-config for that. E.g. if you want to compile with glib-2.0, you can run `pkg-config --cflags glib-2.0 That works sometimes, but is there a general way to find out what to pass to pkg-config besides consulting StackOverflow (or now perhaps ChatGPT)? For example, my recent history looked something like: sudo apt install libopencv-dev pkg-config --libs opencv # did not work pkg-config --libs OpenCV # did not work pkg-config --libs opencv-core # did not work pkg-config --libs opencv45 # did not work pkg-config --libs OpenCV45 # did not work pkg-config --libs opencv4.5 # did not work pkg-config --libs OpenCV4.5 # did not work pkg-config --libs opencv-4.5 # did not work pkg-config --libs OpenCV-4.5 # did not work pkg-config --libs opencv-4 # did not work pkg-config --libs OpenCV-4 # did not work pkg-config --libs opencv4 # success!
- MawKKe 4y agopkg-config --list-all | grep keyword
- lost_tourist 4y agogrep -i :) since case sensitivity matters
- bee_rider 4y agoFor now I’d skip worrying about managing dependencies. Just use system libraries or put your dependencies somewhere you can easily find them. Packaging and shipping code to users is a problem for after you are familiar with the language. Anyway, the typical C program doesn’t pull in a ton of dependencies.
- JHonaker 4y agoYea, I have been learning C recently too. I have found the experience quite a lot more enjoyable than I thought I would. I was originally motivated so that I wouldn't be "scared" to involve myself in working with C FFI calls in the various other languages I use. I've found it just as much fun as Scheme, my favorite language to work in. If you think of Scheme as the minimum-usable implementation of lambda calculus, then C is like the minimum-usable implementation of a Turing machine. They're kind of dual to one another in a very fun way. The one thing I'm really struggling with, like you, is understanding the C "ecosystem". Anything past Makefiles is so complex, especially for my uses. Using something header-only library like STB or a simple library like Raylib is super straightforward, but figuring out what, when, and how to use things like pkg-config, Cmake, Meson, or other tools is a real headache. Does anyone have any favorite resources? I'd also appreciate something more detailed about modern C style, when and why I'd need a custom allocator, or anything else you wouldn't see in K&R or other introduction. PS A lot of people say things like "libc" sucks, you shouldn't be using XYZ function from libc. What should I be using instead? I'm all for learning via implementing things myself, but surely that's not the recommended route for everything in C world.
- enriquto 4y ago> Anything past Makefiles is so complex, especially for my uses. (...) to use things like pkg-config, Cmake, Meson, or other tools is a real headache. Does anyone have any favorite resources? Yes. The GNU make documentation. Just don't use cmake and similar stuff. You can typically rewrite your complex, non-working Cmakelists as simple, straightforward Makefiles.
- irowe 4y agoThe GNU Make documentation is excellent, and you can get t a long way with handwritten Make files, but when you move beyond a few translation units that have different needs, it be becomes much easier to maintain things with CMake.
- lost_tourist 4y agoChoose cmake, learn it well, and it will make learning other systems much easier. If you jump from one build system to the next and just get a cursory understanding you will be hopping around forever.
- UltimateEdge 4y agoOut of curiosity, what resources are you using to learn C? I too have started learning it recently, and I am working through "Modern C" (Manning).