enricorossi.org

Enrico Rossi


Union struct bitfield and endianess in C

Bitfield with struct and union in C (gcc) with endianess

I have updated the union struct and bitfield in C fixing both the endianess of the bit-field and the warning message if the -Wpedantic is used with gcc (bit-field is a GCC extension).

/*
 * Copyright © 2016 Enrico Rossi <e.rossi@tecnobrain.com>
 *
 * This work is free. You can redistribute it and/or modify it under the
 * terms of the Do What The Fuck You Want To Public License, Version 2,
 * as published by Sam Hocevar. See http://www.wtfpl.net/ for more details.
 */

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

union status_t {
	/* GNU GCC only */
	__extension__ struct {

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
		/* lsb */
		uint8_t b0:1;
		uint8_t b1:1;
		uint8_t b2:1;
		uint8_t b3:1;
		uint8_t b4:1;
		uint8_t b5:1;
		uint8_t b6:1;
		uint8_t b7:1;
#else
		/* msb */
		uint8_t b7:1;
		uint8_t b6:1;
		uint8_t b5:1;
		uint8_t b4:1;
		uint8_t b3:1;
		uint8_t b2:1;
		uint8_t b1:1;
		uint8_t b0:1;
#endif

	} bits;

	uint8_t byte;
};

int main(void)
{
	union status_t status;
	int i;

	printf("The size of the union is: %01x byte.\n", sizeof(status));
	printf("The endianess: ");

#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
	printf("LITTLE Endian\n");
#else
	printf("BIG Endian\n");
#endif

	for (i=0; i<8; i++) {
		status.byte = (1<<i);
		printf("Setting bit %d: %01x%01x%01x%01x%01x%01x%01x%01x = 0x%02x\n", i,
				status.bits.b7, status.bits.b6, status.bits.b5, status.bits.b4,
				status.bits.b3, status.bits.b2, status.bits.b1, status.bits.b0,
				status.byte);
	}

	return(0);
}

the output on an x86-64 PC is:

The size of the union is: 1 byte.
The endianess: LITTLE Endian
Setting bit 0: 00000001 = 0x01
Setting bit 1: 00000010 = 0x02
Setting bit 2: 00000100 = 0x04
Setting bit 3: 00001000 = 0x08
Setting bit 4: 00010000 = 0x10
Setting bit 5: 00100000 = 0x20
Setting bit 6: 01000000 = 0x40
Setting bit 7: 10000000 = 0x80