https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106873
Bug ID: 106873 Summary: unsigned short skips byte when used for memory mapping depending on position in structure Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: info at kemalakcam dot com Target Milestone: --- Please move to the correct component in reporting menu as this problem is not necessarily c++ // ============================================================================ // File: ka_example_pointer.cpp // Desc: Software programming example of pointers // Date: 2020/12/25 Ali Kemal Akçam - ka_example_pointer.cpp created. // ============================================================================ // source code shortened to report bug. // memory mapping with unsigned short does not show intented result. // both 'unsigned short' and 'unsigned short int' skips one byte depending on position // tested with // gcc --version // (Debian 4.9.2-10) 4.9.2 // (Debian 8.3.0-6) 8.3.0 // 12.1.0 // gcc version 4.9.2 compiled as // gcc -lstdc++ -std=c++11 ka_example_pointer_very_brief.cpp -o ka_example_pointer_very_brief.o // gcc version 12.1.0 compiled as // gcc -lstdc++ ka_example_pointer_very_brief.cpp -o ka_example_pointer_very_brief.o #include <stdio.h> typedef struct { unsigned char a; // 1 byte unsigned char b; // 1 byte unsigned char c; // 1 byte unsigned char d; // 1 byte unsigned char e; // 1 byte unsigned char f; // 1 byte unsigned char g; // 1 byte unsigned char h; // 1 byte } tsMMP_bytes; // 8 bytes typedef struct { unsigned char a; // 1 byte unsigned short b; // 2 bytes - skips one byte here unsigned char c; // 1 byte unsigned char d; // 1 byte unsigned short e; // 2 bytes - does not skip one byte here unsigned char f; // 1 byte } tsMMP_mixed; // 8 bytes typedef struct { unsigned char a; // 1 byte unsigned char b; // 1 byte unsigned short c; // 2 bytes - does not skip one byte here unsigned char d; // 1 byte unsigned short e; // 2 bytes - skips one byte here unsigned char f; // 1 byte } tsMMP_mixed2; // 8 bytes typedef struct { unsigned char a; // 1 byte unsigned short b; // 2 bytes - skips one byte here unsigned char c; // 1 byte unsigned short d; // 2 bytes - skips one byte here unsigned char e; // 1 byte unsigned char f; // 1 byte } tsMMP_mixed3; // 8 bytes typedef struct { unsigned char l; char h; } tsWord; // signed word DOES NOT WORK! typedef struct { unsigned char a; // 1 byte tsWord b; // 2 bytes - works properly unsigned char c; // 1 byte unsigned char d; // 1 byte tsWord e; // 2 bytes - works properly unsigned char f; // 1 byte } tsMMP_mixed_struct_word; // 8 bytes - correctly maps to another linear memory // 20201225T0311 : Kemal Akcam : Mixed typedef struct works perfectly while using as memory stencil for memory mapping. typedef struct { unsigned char a; unsigned char b; } tsShort; typedef struct { unsigned char a; // 1 byte tsShort b; // 2 bytes - works properly unsigned char c; // 1 byte unsigned char d; // 1 byte tsShort e; // 2 bytes - works properly unsigned char f; // 1 byte } tsMMP_mixed_struct; // 8 bytes - correctly maps to another linear memory class c { public: c(){}; ~c(){}; unsigned char m[16] = { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25 }; void printContent(void); }; void c::printContent(void) { int i; printf("Memory content "); for(i=0; i<16; i++) printf("%X ", m[i]); printf("\n"); printf("tsMMP_bytes "); tsMMP_bytes *pB; pB = (tsMMP_bytes *)&m; printf("%X %X %X %X %X %X %X %X ", pB->a, pB->b, pB->c, pB->d, pB->e, pB->f, pB->g, pB->h); printf("\n"); { printf("tsMMP_mixed "); tsMMP_mixed *pM; pM = (tsMMP_mixed *)&m; printf("%X %X %X %X %X %X <--- 11 is NOT there", pM->a, pM->b, pM->c, pM->d, pM->e, pM->f); printf("\n"); } { printf("tsMMP_mixed2 "); tsMMP_mixed2 *pM; pM = (tsMMP_mixed2 *)&m; printf("%X %X %X %X %X %X <--- 15 is NOT there", pM->a, pM->b, pM->c, pM->d, pM->e, pM->f); printf("\n"); } { printf("tsMMP_mixed3 "); tsMMP_mixed3 *pM; pM = (tsMMP_mixed3 *)&m; printf("%X %X %X %X %X %X <--- 11 and 15 is NOT there", pM->a, pM->b, pM->c, pM->d, pM->e, pM->f); printf("\n"); } printf("tsMMP_mixed_struct "); tsMMP_mixed_struct *pMS; pMS = (tsMMP_mixed_struct *)&m; printf("%X %X %X %X %X %X <--- 11 and 15 is there", pMS->a, pMS->b, pMS->c, pMS->d, pMS->e, pMS->f); printf("\n"); printf("tsMMP_mixed_struct_word "); tsMMP_mixed_struct_word *pMWord; pMWord = (tsMMP_mixed_struct_word *)&m; printf("%X %X %X %X %X %X <--- 11 and 15 is there", pMWord->a, pMWord->b, pMWord->c, pMWord->d, pMWord->e, pMWord->f); printf("\n"); printf("tsMMP_mixed_struct_word "); short int *b = (short int *)&(pMWord->b); short int *e = (short int *)&(pMWord->e); printf(" corr b e %04X %04X ", *b, *e); printf("\n"); printf("tsMMP_mixed_struct_word "); printf("%X %X %X %X %X %X %X %X ", pMWord->a, pMWord->b.h, pMWord->b.l, pMWord->c, pMWord->d, pMWord->e.h, pMWord->e.l, pMWord->f); printf("\n"); } int main(int argc, char **argv) { c *n = new c(); n->printContent(); n->~c(); return 0; } /* Output: ka@localhost:~/projects/ka_projects/pointer_test$ gcc -lstdc++ ka_example_pointer_very_brief.cpp -o ka_example_pointer_very_brief.o ka@localhost:~/projects/ka_projects/pointer_test$ ./ka_example_pointer_very_brief.o Memory content 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 tsMMP_bytes 10 11 12 13 14 15 16 17 tsMMP_mixed 10 1312 14 15 1716 18 <--- 11 is NOT there tsMMP_mixed2 10 11 1312 14 1716 18 <--- 15 is NOT there tsMMP_mixed3 10 1312 14 1716 18 19 <--- 11 and 15 is NOT there tsMMP_mixed_struct 10 1211 13 14 1615 17 <--- 11 and 15 is there tsMMP_mixed_struct_word 10 1211 13 14 1615 17 <--- 11 and 15 is there tsMMP_mixed_struct_word corr b e 1211 1615 tsMMP_mixed_struct_word 10 12 11 13 14 16 15 17 */