Recently, Linus Torvalds publicly dismissed a RISC-V code contribution to the Linux kernel made by a Google engineer as “garbage code”:
https://lkml.org/lkml/2025/8/9/76
First, I think Linus should be more respectful of other people.
In addition, let’s focus on the make_u32_from_two_u16() helper. My understanding is that this is a C preprocessor macro (as the Linux Kernel is mainly written in C). Let’s compare that helper with the explicit code “(a << 16) + b” proposed by Linus.
First, this explicit code is likely wrong, and in fact Linus adds that “maybe you need to add a cast”.
Why should we add a cast? In Linus’s words: “[…] to make sure that ‘b’ doesn’t have high bits that pollutes the end result”. So, what should the explicit code look like according to him? “(a << 16) + (uint16_t)b”?
But let’s do a step back. We should ask ourselves: What are the types of ‘a’ and ‘b’? From the helper’s name, I would think they are two “u16”, so two uint16_t.
If I was asked to write C code that takes two uint16_t values ‘a’ and ‘b’ as input and combines them into a uint32_t, I would write something like that:
((uint32_t)a << 16) | (uint32_t)b
I would use the bitwise OR (|) instead of +; I find it more appropriate as we are working at the bit manipulation level here. But maybe that’s just a matter of personal preference and coding style.
Moreover, I’d use the type casts as shown above, on both ‘a’ and ‘b’.
I’m not sure what Linus meant with ‘b’ potentially having “high bits that pollutes the end result”. Could ‘b’ be a uint32_t? In that case, I would use a bitmask like 0xFFFF with bitwise AND (&) to clear the high bits of ‘b’.
Moreover, I’d probably use better names for ‘a’ and ‘b’, too, like ‘high’ and ‘low’, to make it clear what is the high 16-bit word and what is the low 16-bit word.
So, the correct explicit code is not something as simple as “(a << 16) + b”. You may need to type cast, and you have to pay attention to do it correctly with proper use of parentheses. And you may potentially need to clear the high bits of ‘b’ with a bitmask?
And, if this operation of combining two uint16_t into a uint32_t is done in several places, you sure have many opportunities to introduce bugs with the explicit code that Linus advocates for in his email!
So, it would be much better, clearer, nicer, and safer, to raise the semantic level of the code, and write a helper function or macro to do that combination safely and correctly.
A C macro could look like this:
#include <stdint.h>
#define MAKE_U32_FROM_TWO_U16(high, low) \
( ((uint32_t)(high) << 16) | (uint32_t)(low) )
Should we take into consideration the case in which ‘low’ has higher bits to clear? Then the macro becomes something like this:
#define MAKE_U32_FROM_TWO_U16(high, low) \
( ((uint32_t)(high) << 16) | ((uint32_t)(low) & 0xFFFF))
As you can see, the type casts, the parentheses, the potential bit-masking, do require attention. But once you get the code right, you can safely and conveniently reuse it every time you need!
So, the real garbage code is actually repeatedly writing explicit bug-prone or wrong code, like “(a << 16) + b”! Not hiding such code in a sane helper macro (or function), like shown above.
Instead of a preprocessor macro, we could use an inline helper function. For example, in C++ we could write something like this:
#include <stdint.h>
inline uint32_t make_u32_from_two_u16(uint16_t high, uint16_t low)
{
return (static_cast<uint32_t>(high) << 16) |
static_cast<uint32_t>(low);
}
We could even further refine this function, marking it noexcept, as it’s guaranteed to not throw exceptions.
And we could also make the function constexpr, as it can be evaluated at compile-time when the input arguments are constant.
With these additional refinements, we get:
inline constexpr uint32_t make_u32_from_two_u16(
uint16_t high,
uint16_t low) noexcept
{
return (static_cast<uint32_t>(high) << 16) |
static_cast<uint32_t>(low);
}
