News for hackers. Stuff that matters.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @12:33PM (#36003822)
> that C makes it too hard to use a sorting library that someone competent has written.

This makes no sense to me. What about C makes it hard to use a good library?

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by jjoonathan on Friday May 19, 2023 @12:40PM (#36003917)
C arrays suck on the best of days and qsort requires that you understand function pointers and types which are some of the hairiest C syntax in common use. The C Clockwise Spiral rule is truly special.

It's easy to lose sight of the climb once you're at the top.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @12:48PM (#36004033)
Well, we could debate this, but it's all irrelevant to the assertion that C makes it hard to use good libraries.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by jjoonathan on Friday May 19, 2023 @04:32PM (#36006539)
Oh, right, I forgot that C's library/package management situation sucks so hard that makes the awful syntax look like a comparatively small problem.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @04:57PM (#36006773)
This actually made me laugh out loud. Yes, if your problem with C is that it doesn't need a package management mechanism like some other languages, then C is clearly not for you. But C is very far from the only language like this.

It's a bit like criticizing a fish for having no legs.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Friday May 19, 2023 @05:16PM (#36006952)
> if your problem with C is that it doesn't need a package management mechanism like some other languages

The problem isn't that it doesn't need one, it's that it doesn't have one. I have no idea why you would think that it doesn't need one.

Well there is vcpkg now anyway so it finally does have one.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @05:48PM (#36007215)
I sense that we have some sort of real miscommunication going on here, because the only response I can think of to

> I have no idea why you would think that it doesn't need one.

Is that I have no idea why anyone would think that it does need one.

Perhaps the disconnect is that you are wishing C addresses different use cases than it addresses? That you wish it were a different language? If so, that's fine. Use a more appropriate language for your task. I just find it odd if the criticism of C is that it isn't a different kind of language.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Saturday May 20, 2023 @02:12AM (#36009737)
> Is that I have no idea why anyone would think that it does need one.

For the same reason any language needs one. What is it about C that you think excludes it from the basic requirement of "using third party libraries"?

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by cozzyd on Friday May 19, 2023 @05:33PM (#36007102)
C package management works great on my system.

  # dnf install foo-devel
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Saturday May 20, 2023 @02:15AM (#36009758)
That's suboptimal for many reasons. Package names are not consistent. Installing multiple versions is usually impossible. Huge pain for library authors. Doesn't integrate with build systems usually (even basic pkg-config support is iffy). The command is OS-specific. You can't usually choose the linking method. Difficult to bundle dependencies. Usually out of date. Etc. etc.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by cozzyd on Saturday May 20, 2023 @03:00AM (#36009941)
it works quite well in practice, and unlike pip things don't break every 2 weeks.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by devnullbrain on Friday May 19, 2023 @12:56PM (#36004153)
I'd suspect kernel devs know about function pointers.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by jjoonathan on Friday May 19, 2023 @04:31PM (#36006526)
I'd expect kernel devs to carry lots of bad habits and poorly calibrated intuition from their noob days. Example: "for loops are fine."
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by sgerenser on Friday May 19, 2023 @09:01PM (#36008450)
What’s wrong with for loops?
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by jjoonathan on Sunday May 21, 2023 @11:04AM (#36021706)
They encourage accidentally quadratic behavior if they are easier than calling sort().
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by asveikau on Friday May 19, 2023 @08:30PM (#36008295)
A lot of these comments are like "C is hard if you don't know C and it scares you".

Not to mention kernel mode doesn't want a gigantic library package manager to pull in leftpad() from the internet. As mentioned, the kernel libraries on FreeBSD have a qsort, but they didn't in the original commit from 3 decades ago or whatever.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by me_again on Friday May 19, 2023 @01:30PM (#36004594)
I think it comes down to ecosystem fragmentation.

A lot of languages now have common tooling (cargo for rust, pip for python, etc) which makes it easier to find and incorporate the libraries you want. Apparently there are tools like https://conan.io/ but they're not as widely-adopted.

C's build system is similarly non-uniform. Many packages use Makefiles, others use different build mechanisms.

C has no universally-agreed error handling mechanism or convention. Whether exceptions or golang's error interface, you can generally assume that a random package in most languages will handle errors the way you expect. In C it's a lot more varied.

Similarly memory allocation - sometimes in a larger application you want to customize how malloc and friends work. How and whether you can do that for a C package is non-uniform.

Mind you the C standard library has a sort() function which will have sensible big-O behavior on pretty much any platform. I suspect this specific problem is more to do with this being kernel-mode code which has a lot of special conditions.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @01:35PM (#36004640)
But none of that supports the assertion that C makes it hard to use good libraries. You can even use libraries not written in C if you want.

If the argument is really "it's impossible to make a good library in C", that's different. I'd very much disagree with that, but it would be to the point.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by me_again on Friday May 19, 2023 @02:04PM (#36005018)
I'm saying "it is harder to consume good libraries in C, because it is harder to find them & harder to build them; and once you have done both, you find that good library A and good library B work in very different ways, so you have to do more work to adapt".

And I haven't mentioned the lack of a strong universal string type, the way many libraries typedef their own family of different kinds of integer, the way one library will require you to free() a returned structure and another will require you to call my_library_free()...

It all adds up to additional friction.

You don't have to agree! Maybe I am out of date, I haven't really dealt with this since the mid 2000's. I'd be thrilled to hear this isn't an issue any more.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by pjmlp on Friday May 19, 2023 @02:25PM (#36005216)
Although I usually rant about C, using libraries is surely not a problem specifically in the world of UNIX package managers.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @03:41PM (#36005986)
> You don't have to agree!

It's not really a matter of whether or not I agree. I was just trying to understand what the assertion was!

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by giantrobot on Friday May 19, 2023 @03:36PM (#36005951)
The original assertion was about difficulty of using C libraries in the kernel or bootloader. In the bootloader you're the OS. There's no file system, no dynamic linker, and no processes. There's no guarantee some third party library will work in that environment. It might but it's work to make sure it does or adapt it if it doesn't.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by Eduard on Friday May 19, 2023 @07:09PM (#36007848)
Let's say you want to develop a CLI tool in C for crawling a website's sitemap.xml as advertised by the website's robots.txt. How would you approach this development in C?

With e.g. Java, Javascript, PHP, and Python it's clear to me.

With C, I don't know.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by cozzyd on Saturday May 20, 2023 @02:58AM (#36009931)
libcurl and expat (or one of a zillion other XML libraries)?
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by Dylan16807 on Friday May 19, 2023 @02:13PM (#36005097)
Custom memory allocation is pretty optional and a lot of the time could be handled with a single buffer.

Outside of that you don't need to deal with exceptions in a sorting library, and you can happily make it a single .c and .h

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by dmitrygr on Friday May 19, 2023 @02:49PM (#36005495)
> cargo for rust, pip for python, etc

GOOD! I love that C lacks this pollution. Means that code is written for-purpose and tuned for-purpose.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by jcparkyn on Friday May 19, 2023 @11:48PM (#36009214)
... except in this case (and many others), where it was written for-purpose and then never tuned.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by kaba0 on Saturday May 20, 2023 @03:22AM (#36010033)
Is the purpose opening up new vulnerabilities?
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by palata on Friday May 19, 2023 @06:03PM (#36007321)
I am always amazed by arguments that say that not having a language package manager like cargo or pip makes it hard.

Really? Is it really considered hard to link a library without them? Am I so old that somehow I grew up in a world where linking a library was not considered black magic?

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by chlorion on Friday May 19, 2023 @08:42PM (#36008354)
There is a lot more going on here.

The first issue is actually downloading the dependencies, doing this manually quickly becomes infeasible for any non-trivial project.

The second issue is keeping everything updated, and making sure that all packages are compatible with all other packages. Doing this manually is also not easy.

With C specifically, you need to wrangle different build systems, and once you have them built and "installed", you need to figure out which linker and compiler flags are needed to consume the libraries.

If you are working on a small project with maybe a few dependencies you can do this by hand, but when you get to say, 15 dependencies, it quickly becomes very difficult.

You can use the system package manager on some systems to install libraries I guess (assuming it has the packages and versions that you need), in this case manually managing things could be a lot easier, but you still should be using pkg-config for portability purposes.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by yjftsjthsd-h on Friday May 19, 2023 @09:20PM (#36008561)
Okay, but this is FreeBSD. All they have to do is import whatever code into src and use it.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by zrm on Friday May 19, 2023 @01:42PM (#36004721)
> This makes no sense to me. What about C makes it hard to use a good library?

It doesn't have templates/generics.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by kevin_thibedeau on Friday May 19, 2023 @02:29PM (#36005264)
C11 added (limited) generic support
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by remexre on Friday May 19, 2023 @05:34PM (#36007109)
You can't specialize a generic algorithm for specific operations and data structures; in C++ terms, it gives you overloading, not templates.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by kevin_thibedeau on Friday May 19, 2023 @09:23PM (#36008574)
It gives generic programming. C++ templates aren't the only possible implementation.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by kaba0 on Saturday May 20, 2023 @03:25AM (#36010045)
So where is a generic vector data structure written in plain C that is efficient (that is, doesn’t store pointers to elements).
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by zrm on Friday May 19, 2023 @06:00PM (#36007300)
They used "_Generic" as a keyword but it doesn't really do that.

Suppose I need to define a copy assignment operator for the library's sort function to use. Is there a good way to overload it? Can the library know what the size of each element is based on its type without having to pass it in as a parameter?

You can pass function pointers to the library, but that quickly becomes awful.

  /* sort for basic integer types */
  void lib_sort_u8(uint8_t *a, size_t count);
  void lib_sort_i8(int8_t *a, size_t count);
  void lib_sort_u16(uint16_t *a, size_t count);
  void lib_sort_i16(int16_t *a, size_t count);
  void lib_sort_u32(uint32_t *a, size_t count);
  void lib_sort_i32(int32_t *a, size_t count);
  void lib_sort_u64(uint64_t *a, size_t count);
  void lib_sort_i64(int64_t *a, size_t count);
  /* specify a comparator */
  void lib_sort_comp(void *start, size_t nmemb, size_t size, int (*compar), const void *, const void *));
  /* specify a comparator and an assignment operator */
  void lib_sort_assign_comp(void *start, size_t nmemb, size_t size, void (*assign)(void *, const void *), int (*compar)(const void *, const void *));
  /* specify a comparator, an assignment operator, and ... */
Or, you get one function that takes all of the arguments and have to define and pass in a bunch of function pointers and type size parameters that are each an opportunity for bugs or UB in order to sort a simple array of integers.

If my type needs a custom assignment operator, I need each library I use to take that as an argument. One expects the function pointer to take the arguments in the order (src, dst), another as (dst, src), a third specifies the return value as int instead of void, a fourth takes the source argument as "void *" instead of "const void *" in case you want to implement move semantics and a fifth doesn't support custom assignment operators at all.

It's no surprise that people prefer to avoid this.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by acuozzo on Friday May 19, 2023 @04:48PM (#36006693)
The lack of namespaces is of far greater consequence.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by Jorengarenar on Friday May 19, 2023 @05:45PM (#36007203)
LIBNAME_actual_function_name()
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by acuozzo on Monday May 22, 2023 @04:35PM (#36036368)
Annoyance #1: External symbols are expected to be unique within 31 characters according to the standard, so you're limited to a few namespace "levels", at most.

curl_easy_option_by_name() is already up to 24 characters and there's only two "levels" in curl_easy_*.

Annoyance #2: There's no formal registrar for LIBNAME. This isn't a big deal for popular libraries, but it's a pain having to keep a locally-modified copy of a less popular dependency just because it shares its name with another less popular dependency.

Annoyance #3: LIBNAME_actual_function_name() is a pain to read and using either the preprocessor or static inlines to locally alias function names for the sake of readability is silly.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by Jorengarenar on Monday May 22, 2023 @05:53PM (#36037185)
@1: The limits are considered obsolete since C89 and implementations are encouraged to avoid them whenever possible. I think the same way we disregard non ASCII character sets, non two's complement encodings and similar, we are safe in assuming sane implementation being able to handle longer names. And being honest, if given implementation isn't capable of more than 31 significant characters, then it would have problems with namespaces too.

@2: Agree, although I don't recall this ever happening to me.

@3: Is it? How is libname::actual_function_name() much better?

I actually like to use libname__actual_function_name(), as it further separates "namespace" from function name (unless we need compatibility with C++, as IIRC it reserves all double underscores, not only at the beginning).

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by acuozzo on Tuesday May 23, 2023 @10:09AM (#36044547)
> @1: The limits are considered obsolete since C89 and implementations are encouraged to avoid them whenever possible.

This is still the case in C11, Section 5.2.4.1. Did this change in the most recent standard?

> @2: Agree, although I don't recall this ever happening to me.

It happened to me once. I ran across a library from 1994 and another from the 2010s which shared a simple name like "libamc". I'll comb through my records later to figure out the actual name.

> @3: Is it? How is libname::actual_function_name() much better?

It's not, but I wasn't thinking of C++ specifically. (I don't know C++. I've somehow managed to avoid it in many years of writing C.)

I was thinking more like the file-local namespace clobbering offered by Python e.g., from LIBNAME import actual_function_name.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by Jorengarenar on Tuesday May 23, 2023 @10:38AM (#36044963)
> This is still the case in C11, Section 5.2.4.1. Did this change in the most recent standard?

Well, no, it's still marked "just" obsolete. For it to be deprecated or removed there would need to be anybody caring about it enough to put some work. But since it doesn't affect vendors at all (they can just ignore) and users don't complain, it's just a forgotten "law" - still law, but a dead one.

> I was thinking more like the file-local namespace clobbering offered by Python e.g., from LIBNAME import actual_function_name.

Oh, that's... way more than just namespaces. Way more. That would require more fundamental changes and additions. C++ just added modules in C++20 (not sure how well those will catch on), but I don't think something like that is to be expected in C for feasible future.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Friday May 19, 2023 @03:56PM (#36006149)
There's no standard build system. Think about how you add a dependency in Rust, Go, JavaScript, even Python.

Now do it in C/C++. Absolute nightmare.

Look at how many header-only C++ libraries there are out there. They're making compilation time drastically worse purely to avoid the need to faff with a shitty build system. It's a good trade-off too. I use header-only libraries where possible. They're convenient and popular.

Actually vcpkg seems to be going some way to fixing that but I have yet to convince my co-workers to use it.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @05:05PM (#36006837)
> to avoid the need to faff with a shitty build system.

Then maybe don't use a shitty build system?

It's true, C is not trying to be a programming environment or tech stack. It's a language, that's it. Whether or not that's desirable depends on what you're trying to do, it's not something that is good or bad in some absolute sense.

You have your choice of build systems, so pick one that meets your needs.

Vcpkg isn't for me, either, because it doesn't solve any problem I have. If it does for you, awesome!

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Friday May 19, 2023 @05:18PM (#36006970)
> You have your choice of build systems, so pick one that meets your needs.

And can I pick the one that my dependencies use too? Didn't think so.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @05:40PM (#36007151)
Your dependencies have already been built. You're just linking to them. So yes, you can.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by inferiorhuman on Friday May 19, 2023 @06:37PM (#36007562)
And what if the dependencies haven't been built yet?
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by icedchai on Friday May 19, 2023 @06:51PM (#36007708)
Build them and install them in /usr/local, just like we did 30 years ago.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by inferiorhuman on Friday May 19, 2023 @07:27PM (#36007959)
With what? The whole point of this line of discussion is that building stuff in C is suboptimal, often requiring the end user to juggle n different build systems by hand to get all the dependencies installed.

Since we're talking FreeBSD here, thirty years ago we had Modula-3 whose build system is lightyears ahead of anything make based.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by icedchai on Friday May 19, 2023 @07:52PM (#36008102)
You already answered your own question: with whatever tools that dependency requires, often ./configure && make && make install

In the event you find yourself doing this constantly, write a shell script.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by inferiorhuman on Friday May 19, 2023 @10:03PM (#36008764)
And now we're back at: this is why C is more difficult, for no good reason, than the alternatives. For small projects that you're only building locally, your approach may work. Once you expect any sort of cross-platform compatibility and/or start distributing your project to others, this approach falls apart and fast. Instead of focusing on development you'll be focusing on playing whack-a-mole with incompatibilities between the different shells (or versions of make, etc.) offered on different operating systems.

Again the problem is that no package/dependency management for C/C++ means that C is balkanized and more difficult to deal with compared to other languages. Using third party libraries in C is far more difficult and error prone than it ought to be.

Pretty much every language that provides more comprehensive dependency management also provides easy enough access to allow you to NIH/DIY it if you need/want to. For instance contrast this with something like rust where cargo is standard across all supported platforms and provides proper dependency management. You can still call the rust compiler (rustc) and whatever linker yourself if you so desire.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by IshKebab on Saturday May 20, 2023 @02:18AM (#36009775)
Honestly if you lack the vision to see why that sucks I really suggest you try a language with good package management - e.g. Go or Rust. Maybe it will make it easier to see all the problems with the traditional C approach if you can see how it should work.
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by icedchai on Saturday May 20, 2023 @02:01PM (#36014120)
C and C++ dependency installation is "sub-optimal" but it is certainly well understood. The fact that there are many cross platform, open source projects written in C and C++ proves this. If you can't deal with makefiles and scripts, maybe stick to Go and Rust?
Re:FreeBSD spends 7% of its boot time running a bubblesort o... by steveklabnik on Saturday May 20, 2023 @02:33PM (#36014415)
> If you can't deal with makefiles and scripts, maybe stick to Go and Rust?

Many people will in fact do just this.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by inferiorhuman on Monday May 22, 2023 @12:18AM (#36027409)

  C and C++ dependency installation is "sub-optimal" but it is certainly well
  understood. The fact that there are many cross platform, open source projects
  written in C and C++ proves this.
Nope. It proves that people have found work arounds up to and including cargo culting things. Any large enough project is going to rely on something else to generate the makefiles, and if you depend on anything large enough you're gonna get stuck having to build and/or install whatever other makefile generators are required. Simply put it's an archaic mess.

  If you can't deal with makefiles and scripts, maybe stick to Go and Rust?
To be clear it's not that I can't deal with makefiles it's that I don't find it a good use of my time*. Take, for instance, the FreeBSD ports tree. make(1) is its achilles heal and the main reason it's obscenely slow to deal with (even compared to something like portage). Besides, doing anything by hand is inherently error prone be it bounds checking array access or cobbling together dependency management.

* And, sure, in years past I wrote a drop-in replacement for automake/autoconf in perl whose big (speed) advantage was that it didn't spawn a new shell for each check. It was a neat hack, but that's all anything papering over the make(1) interface is.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by JohnFen on Friday May 19, 2023 @07:00PM (#36007780)
Then build them. I'm not seeing the issue here, to be honest, so I'm not sure what I should be addressing.

If the issue is that you don't like how the dependency has arranged to build (I'm not sure why you'd actually care, but just in case...), then port the makefile (or whatever) to your preferred system.

Or, another guess, is the issue that you want to build all your dependencies as if they were an integral part of your own project? If that's the case, I would argue that you're doing it wrong and another tech stack would make you happier.

Re:FreeBSD spends 7% of its boot time running a bubblesort o... by kaba0 on Saturday May 20, 2023 @03:20AM (#36010025)
C can’t be used to implement a good library for many problems due to being inexpressive. For example, you can’t write an efficient, generic vector data structure, but sort functions are also only fast due to the compiler’s smartness — passing a function pointer would be strictly slower.

Though this has not much relevance here as it is about assembly.