Here's the code under consideration:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
char buffer[512];
int pos;
int posf;
int i;
struct timeval *tv;
int main(int argc, char **argv)
{
    pos = 0;
    for (i = 0; i < 512; i++) buffer[i] = 0;
    for (i = 0; i < 4; i++)
    {
        printf("pos = %d\n", pos);
        *(int *)(buffer + pos + 4) = 0x12345678;
        pos += 9;
    }
    for (i = 0; i < 9 * 4; i++)
    {
        printf(" %02X", (int)(unsigned char)*(buffer + i));
        if ((i % 9) == 8) printf("\n");
    }
    printf("\n");
    // ---  
    pos = 0;
    for (i = 0; i < 512; i++) buffer[i] = 0;
    *(int *)(buffer + 4) = 0x12345678;
    *(int *)(buffer + 9 + 4) = 0x12345678;
    *(int *)(buffer + 18 + 4) = 0x12345678;
    *(int *)(buffer + 27 + 4) = 0x12345678;
    for (i = 0; i < 9 * 4; i++)
    {
        printf(" %02X", (int)(unsigned char)*(buffer + i));
        if ((i % 9) == 8) printf("\n");
    }
    printf("\n");
    return 0;
}
And the output of code is
pos = 0
pos = 9
pos = 18
pos = 27
 00 00 00 00 78 56 34 12 00
 00 00 00 78 56 34 12 00 00
 00 00 78 56 34 12 00 00 00
 00 78 56 34 12 00 00 00 00
 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00
 00 00 00 00 78 56 34 12 00
I can not get why
*(int *)(buffer + pos + 4) = 0x12345678;
is being placed into the address aligned to size of int (4 bytes). I expect the following actions during the execution of this command:
- pointer to buffer, which is char*, increased by the value ofpos(0, 9, 18, 27) and then increased by 4. The resulting pointer ischar*pointing to char array index[pos + 4];
- char*pointer in the brackets is being converted to the- int*, causing resulting pointer addressing integer of 4 bytes size at base location- (buffer + pos + 4)and integer array index- [0];
- resulting int*location is being stored with bytes 78 56 34 12 in this order (little endian system).
Instead I see pointer in brackets being aligned to size of int (4 bytes), however direct addressing using constants (see second piece of code) works properly as expected.
- target CPU is i.MX287 (ARM9);
- target operating system is OpenWrt Linux [...] 3.18.29 #431 Fri Feb 11 15:57:31 2022 armv5tejl GNU/Linux;
- compiled on Linux [...] 4.15.0-142-generic #146~16.04.1-Ubuntu SMP Tue Apr 13 09:27:15 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux, installed in Virtual machine;
- GCC compiler version gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609
- I compile as a part of whole system image compilation, flags are CFLAGS = -Os -Wall -Wmissing-declarations -g3.
Update: thanks to Andrew Henle, I now replace
*(int*)(buffer + pos + 4) = 0x12345678;
with
        buffer[pos + 4] = value & 0xff;
        buffer[pos + 5] = (value >> 8) & 0xff;
        buffer[pos + 6] = (value >> 16) & 0xff;
        buffer[pos + 7] = (value >> 24) & 0xff;
and can't believe I must do it on 32-bit microprocessor system, whatever architecture it has, and that GCC is not able to properly slice int into bytes or partial int words and perform RMW for those parts.
 
     
    