5 ms·
That series of macros is a nice demonstration of the incredible effort it takes to attempt the most basic generic programming in C. Perhaps it would be more pro
by jonathrg 2y ago
That series of macros is a nice demonstration of the incredible effort it takes to attempt the most basic generic programming in C. Perhaps it would be more productive to just accept the limitations of the language and define a version of `min` and `max` for each type.
- lifthrasiir 2y agoThat will make `typedef` much less useful, though. C is the real problem; not the attempt to do generic programming in C. (And `_Generic` won't solve this problem anyway. Only a GCC extension of statement expressions will.)
- asplake 2y agoAlso a demonstration of how much work other compilers do for you behind the scenes.
- Groxx 2y agoEhhh... not much more so than how much `npm install` hides. These macros are part of a gigantic tower of absurdity that costs many, many times more than they need to, but we use them because dev time is more valuable than CPU time.
- rerdavies 2y agoDev time spent waiting for compiles is way more expensive than CPU time.
- jonathrg 2y agoA compiler for a language with generic types will definitely do less work to implement generic min/max than the C preprocessor has to do in order to perform all the text substitutions generated by these macros.
- asplake 2y agoOh totally! It has the information to do it both properly and efficiently.
- usr1106 2y agoOr a demonstration about the poor state of programming languages in 2024. Of course there are others than C. But not many suitable for writing a kernel. And no obvious choice for what Linux could do today. Of course they are starting with Rust, but nobody can predict when that will make the last C macro unnecessary. Unless your prediction is never...
- pjmlp 2y agoPlenty of kernels have been written in other languages, naturally UNIX/POSIX folks can hardly think of something else. Even Linus accepting Rust is kind of interesting, because his C++ rants also apply to plenty of Rust code bases.
- gary_0 2y agoDoesn't Rust's `no_std` make it easy to throw out idioms you can't use (or don't like) and just keep the syntax and most of the tooling? I recall that one of Linus's preconditions for inclusion was that Rust's default of panic!ing on allocation failures had to be overrideable. Whereas C++ tends to make you eat the whole enchilada.
- pjmlp 2y agoC++ compilers have similar options, e.g. VC++ has /kernel, and there is the freestanding standard as well. Also see Embedded C++ as used by macOS IO Kit, which thankfully there isn't a Linus at Apple. Regarding Rust, no_std, doesn't change the npm like dependencies, macro festival (with two ways of doing all kinds of stuff), abstraction party with type driven development, the compile times.
- tialaramex 2y agoThe C++ "freestanding" even when the current round of work is completed, is nowhere close to Rust's core. Partly this is because Rust thought about this earlier, and partly it's because of the relationship between C++ and the allocator, having operators for a feature which might not even exist on your target, awkward.
- peheje 2y agoWhy don't they define a min/max for each primitive type? How many are there, 15?
- kzrdude 2y agoEven use a macro to define all typed min max macros
- wahern 2y agoThe reason the current macro is so complex is because it supports mixed types while avoiding (failing on) integer promotion bugs. A version supporting arguments of all the same type would be just as trivial as in C++ (albeit relying on GCC extensions like statement expressions).
- tempfile 2y agoThis is addressed if you chase down the original kernel mailing list thread (the "flamewar" linked in the article). It was important to Linus that the macro was actually min/max and not min_slong max_uint etc, so that people couldn't "accidentally" use the untyped version. In other words he was trying quite hard to "force" people to use these macros. If you would then say "why doesn't min/max just implement a switch on each primitive type", I think on some level it does just do that.
- colonwqbang 2y agoGenericity is not really the issue as I see it. The basic K&R macro using ?: is fully generic. The problem is that C has implicit conversion between essentially any numeric types. The main point of the kernel macro was to prevent such conversions. I think implicit type conversion is a mistake, perhaps one of the few true design flaws in C. Languages like haskell and rust went with explicit conversions which is probably a better idea overall, even if it does increase the code verbosity a bit. C++ instead doubled down and added many more ways for implicit conversions to happen.
- PaulDavisThe1st 2y ago> C++ instead doubled down and added many more ways for implicit conversions to happen. but also allows you to turn them off for objects, thankfully.