The alternative solution, based on arithmetic, may be be valid, but may as well contain a bug.
This is a very good point. Personally, I worked with hand-maintained bit shift fests until one day I hunted for a bug for hours; a bug which was caused by mistyping < instead of <<. Then I started thinking,
there has to be a better way.
The problem with the arithmetic version, whether based on / % * or << >> | &, doesn't matter, is that it is error prone manual work. This is the preferred solution when the operations are small, simple and the number of such operations is small. Good for beginners, test programs, and so on. Just typecast
everything using the stdint typedefs, and use a lot of parentheses everywhere.
This is also why I think the OP of this thread should go forward with janoc's approach. But it's not the generic solution.
Because when you start writing a full parser with dozens of data fields and you have 100 lines full of such bit shifting fest, it just falls apart. Then, you need indeed to look at the C standard to find out that interpreting any arbitrary data as an array of bytes, or char*, is
indeed well defined; it's not only normal, it's also allowed by even the strictest views of language lawyers. Now if you extend this to a more generic pattern involving reverse operation, which is indeed required to take the advantage of the pattern, you need to understand the traps and their workarounds. Tough luck, C ain't easy. And practical C is different to "standard C". And microcontroller code is never perfectly portable anyway. Maybe you can accept the fact that you won't migrate the code from a little endian machine to a big endian one, or vice versa.
So really, I do see the bitshifting data partitioning as a
beginner pattern. It's not bad, but it's not scalable. When you learn more about C, you start understanding how to avoid such error-prone process and have some better, but on more powerful tools, there are traps you need to know about.
Regarding alignment; most proper CPUs give ALIGNMENT ERROR interrupt (for example, busfault), making it easy to see what happened, why, and where, and fix it. Instead, a mistyped bitshift somewhere is completely hidden and only causes some certain parameter or field to act strangely. Almost impossible to debug; you may not even know you have a problem.