preprocessor-toolchain · advanced · ~15 min

Compile-Time and Run-Time Endian Converter

Detect host byte order and perform safe endian conversions with bitwise manipulations.

Challenge

Network protocols use Big-Endian (Network Byte Order), whereas most modern CPUs (x86-64, ARM) operate in Little-Endian. Portable network software checks endianness and applies bit-shift byte swaps.

Your Task

Implement:

int is_little_endian(void);
uint16_t swap_uint16(uint16_t val);
uint32_t swap_uint32(uint32_t val);
uint32_t to_network_order_u32(uint32_t host_val);

Rules

  1. is_little_endian(): inspects a 16-bit integer 0x0102 through a uint8_t* pointer. If the first byte is 0x02, return 1 (little-endian). If 0x01, return 0 (big-endian).
  2. swap_uint16(val): swaps the 2 bytes of val using bitwise shift operators.
  3. swap_uint32(val): reverses the 4 bytes of val using bitwise shift operators.
  4. to_network_order_u32(host_val): converts host-order 32-bit integer to big-endian network byte order. If host is little-endian, returns swap_uint32(host_val). If host is already big-endian, returns host_val untouched.

Example

swap_uint16(0x1234); // returns 0x3412
swap_uint32(0x12345678); // returns 0x78563412

Input format

Integer values to inspect or swap.

Output format

Returns endian detection boolean or byte-swapped integers.

Constraints

Must use bitwise shifts: << and >> with uint32_t masks.

Starter code

#include <stdint.h>

int is_little_endian(void) {
    return 0;
}
uint16_t swap_uint16(uint16_t val) {
    (void)val; return 0;
}
uint32_t swap_uint32(uint32_t val) {
    (void)val; return 0;
}
uint32_t to_network_order_u32(uint32_t host_val) {
    (void)host_val; return 0;
}

Common mistakes

Sign extension bugs when shifting signed types; wrong bitmask offsets.

Edge cases to handle

swap_uint32(0) == 0; swap_uint32(0xFFFFFFFF) == 0xFFFFFFFF; symmetric swap: swap(swap(x)) == x.

Background lessons

Solve this exercise in the browser editor — compile and run against the test harness, no setup required.