In other words, according to the C standard, is this code safe? (Assume uint8_t is one byte)
void detectEndianness(void){
u
Quoting from n1570:
6.5.2.3 Structure and union members - p3
A postfix expression followed by the . operator and an identifier designates a member of a structure or union object. The value is that of the named member, and is an lvalue if the first expression is an lvalue.
6.2.6 Representations of types / 1 General - p7
When a value is stored in a member of an object of union type, the bytes of the object representation that do not correspond to that member but do correspond to other members take unspecified values.
It's allowed. And your use case could even be considered one intended purpose, if note 95 is taken into account (despite being only informative):
If the member used to read the contents of a union object is not the same as the member last used to store a value in the object, the appropriate part of the object representation of the value is reinterpreted as an object representation in the new type as described in 6.2.6 (a process sometimes called "type punning"). This might be a trap representation.
Now, since the uintN_t family of types are defined to have no padding bits
7.20.1.1 Exact-width integer types - p2
The typedef name uintN_t designates an unsigned integer type with width N and no padding bits. Thus, uint24_t denotes such an unsigned integer type with a width of exactly 24 bits.
All their bit representations are valid values, no trap representations are possible. So we must conclude that it will indeed check for the endianess of uint16_t.