/* Standard Includes */ /*****************************************************************************/ /* STDINT.H v16.9.7 */ /* */ /* Copyright (c) 2002-2018 Texas Instruments Incorporated */ /* http://www.ti.com/ */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* */ /* Redistributions of source code must retain the above copyright */ /* notice, this list of conditions and the following disclaimer. */ /* */ /* Redistributions in binary form must reproduce the above copyright */ /* notice, this list of conditions and the following disclaimer in */ /* the documentation and/or other materials provided with the */ /* distribution. */ /* */ /* Neither the name of Texas Instruments Incorporated nor the names */ /* of its contributors may be used to endorse or promote products */ /* derived from this software without specific prior written */ /* permission. */ /* */ /* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ /* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ /* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */ /* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */ /* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ /* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY */ /* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */ /* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE */ /* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* */ /*****************************************************************************/ /* 7.18.1.1 Exact-width integer types */ typedef signed char int8_t; typedef unsigned char uint8_t; typedef short int16_t; typedef unsigned short uint16_t; typedef int int32_t; typedef unsigned int uint32_t; typedef long long int64_t; typedef unsigned long long uint64_t; /* 7.18.1.2 Minimum-width integer types */ typedef int8_t int_least8_t; typedef uint8_t uint_least8_t; typedef int16_t int_least16_t; typedef uint16_t uint_least16_t; typedef int32_t int_least32_t; typedef uint32_t uint_least32_t; typedef int64_t int_least64_t; typedef uint64_t uint_least64_t; /* 7.18.1.3 Fastest minimum-width integer types */ typedef int32_t int_fast8_t; typedef uint32_t uint_fast8_t; typedef int32_t int_fast16_t; typedef uint32_t uint_fast16_t; typedef int32_t int_fast32_t; typedef uint32_t uint_fast32_t; typedef int64_t int_fast64_t; typedef uint64_t uint_fast64_t; /* 7.18.1.4 Integer types capable of holding object pointers */ typedef int intptr_t; typedef unsigned int uintptr_t; /* 7.18.1.5 Greatest-width integer types */ typedef long long intmax_t; typedef unsigned long long uintmax_t; /* According to footnotes in the 1999 C standard, "C++ implementations should define these macros only when __STDC_LIMIT_MACROS is defined before is included." */ /* 7.18.2 Limits of specified width integer types */ /* 7.18.3 Limits of other integer types */ /* 7.18.4.1 Macros for minimum-width integer constants */ /* There is a defect report filed against the C99 standard concerning how the (U)INTN_C macros should be implemented. Please refer to -- http://wwwold.dkuug.dk/JTC1/SC22/WG14/www/docs/dr_209.htm for more information. These macros are implemented according to the suggestion given at this web site. */ /* 7.18.4.2 Macros for greatest-width integer constants */ typedef struct st_outerStruct_1 { union { uint8_t rawData[6]; struct st_innerSt1 { // Byte 1 uint8_t byte1_bit1 : 1; uint8_t byte1_bit2 : 1; uint8_t byte1_bit3 : 1; uint8_t byte1_bit4 : 1; uint8_t byte1_bit5 : 1; uint8_t byte1_bit6 : 1; uint8_t byte1_bit7 : 1; uint8_t byte1_bit8 : 1; // Byte 2 uint8_t byte2_bit1 : 1; uint8_t byte2_bit2 : 1; uint8_t byte2_bit3 : 1; uint8_t byte2_bit4 : 1; uint8_t byte2_bit5 : 1; uint8_t byte2_bit6 : 1; uint8_t byte2_bit7 : 1; uint8_t byte2_bit8 : 1; // Byte 3,4,5,6 uint32_t number_u32; } innerSt1 __attribute__ ((__packed__)); } __attribute__ ((__packed__)); } outerStruct_1; typedef struct st_outerStruct_2 { union { uint8_t rawData[6]; struct __attribute__ ((__packed__)) st_innerSt2 { // Byte 1 uint8_t byte1_bit1 : 1; uint8_t byte1_bit2 : 1; uint8_t byte1_bit3 : 1; uint8_t byte1_bit4 : 1; uint8_t byte1_bit5 : 1; uint8_t byte1_bit6 : 1; uint8_t byte1_bit7 : 1; uint8_t byte1_bit8 : 1; // Byte 2 uint8_t byte2_bit1 : 1; uint8_t byte2_bit2 : 1; uint8_t byte2_bit3 : 1; uint8_t byte2_bit4 : 1; uint8_t byte2_bit5 : 1; uint8_t byte2_bit6 : 1; uint8_t byte2_bit7 : 1; uint8_t byte2_bit8 : 1; // Byte 3,4,5,6 uint32_t number_u32; } innerSt2; } __attribute__ ((__packed__)); } outerStruct_2; typedef struct st_outerStruct_3 { union { uint8_t rawData[6]; struct { // Byte 1 uint8_t byte1_bit1 : 1; uint8_t byte1_bit2 : 1; uint8_t byte1_bit3 : 1; uint8_t byte1_bit4 : 1; uint8_t byte1_bit5 : 1; uint8_t byte1_bit6 : 1; uint8_t byte1_bit7 : 1; uint8_t byte1_bit8 : 1; // Byte 2 uint8_t byte2_bit1 : 1; uint8_t byte2_bit2 : 1; uint8_t byte2_bit3 : 1; uint8_t byte2_bit4 : 1; uint8_t byte2_bit5 : 1; uint8_t byte2_bit6 : 1; uint8_t byte2_bit7 : 1; uint8_t byte2_bit8 : 1; // Byte 3,4,5,6 uint32_t number_u32; } __attribute__ ((__packed__)); } __attribute__ ((__packed__)); } outerStruct_3; int main(void) { outerStruct_1 st1; // Inner struct is named, packed attribute at the END of the inner struct outerStruct_2 st2; // Inner struct is named, packed attribute at the START of the inner struct outerStruct_3 st3; // Inner struct is NOT named, packed attribute at the END of the inner struct st1.innerSt1.number_u32 = 0xaabbccdd; // rawData field is wrong - the upper 2 bytes have been dropped - looks like number_u32 has been 32bit aligned. st2.innerSt2.number_u32 = 0xaabbccdd; // rawData field is right st3.number_u32 = 0xaabbccdd; // rawData field is right while(1){} }