2020-05-04 08:05 PM
I am a little bit confusing with Address calculation using sizeof() operator.
I am writing a program for DMA transfer half a buffer in a time.
Such as,
---------
1st: HAL_SPI_Transmit_DMA(&hspi1, ptr1, buf_len/2) ;
2nd: HAL_SPI_Transmit_DMA(&hspi1, ptr2, buf_len/2) ;
---------
where ptr1 is pointer to DATA[0] and ptr2 is pointer to DATA[10].
However, when I wrote 2nd one as,
---------
HAL_SPI_Transmit_DMA(&hspi1, ptr1+sizeof(uint16_t)*10, buf_len/2) ;
---------
I got wrong addres for ptr2.
Therefore, I checked the result of sizeof() as below, and found sizeof(uint16_t) does not return same value in address calculation.
---------
uint16_t Data[20] ;
uint16_t * addr0 = Data ; // 0x2000ffbc or 536936380 [base]
uint16_t * addr1 = &(Data[10]) ; // 0x2000ffe4 or 536936420 [base + 20]
uint16_t * addr2 = Data + sizeof(uint16_t)*10 ; // 0x2000ffd0 or 536936400 [base + 40]
int size = sizeof(uint16_t) ; // size = 2
int arraysize = sizeof(Data) / sizeof(Data[0]) ; // arraysize = 20
---------
I suppose uint16_t is 2 byte data as shown in sizeof(uint16_t). Otherwise how can I align 2 byte data in a buffer?
Kindly enlighten me!
Thank you,
2020-05-04 08:52 PM
Incrementing a pointer of type (uint16_t *) increases its address by the size of the value it points to, which is 2 in this case.
So instead of doing "Data + sizeof(uint16_t)*10", you should just be doing "Data + 10".
int arraysize = sizeof(Data) / sizeof(Data[0]) = 40 / 2 = 20;
Seems fine to me. sizeof(Data) is the size in bytes of the Data array.
2020-05-04 10:59 PM
Dear TDK,
Thank you very much for your kind answer.
I understood as this.
Address calculation is not done in byte, but done in sizeof(Data) or sizeof(Data_type).
Therefore, I should have written 2nd case as, (not checked yet.)
HAL_SPI_Transmit_DMA(&hspi1, (uint16_t *)((uint8_t*)ptr1+sizeof(uint16_t)*10), buf_len/2) ;
Many thanks.
2020-05-05 12:29 AM
This is why the Go language dumped pointer arithmetic. Too confusing for modern coders.
-- pa
2020-05-06 03:10 AM
> Address calculation is not done in byte, but done in sizeof(Data) or sizeof(Data_type).
The first is wrong, the second is right. In fact is even simpler - the ptr1 pointer address calculation is done in units of sizeof(*ptr1).
> Therefore, I should have written 2nd case as... (uint8_t*)ptr1+sizeof(uint16_t)*10
It's correct, but terrible. TDK already told you what to write! It's just ptr1 + 10 or &ptr1[10].
> Too confusing for modern coders.
The above example... If a "developer" is not able of grasping such a trivial thing, he's not able of developing anything useful anyway.