I'm newbie C programmer working on maintaining some legacy embedded C code that looks problematic. In the following snippets I have simplified:
UINT16 adcFunc(UINT8 adc, UINT8 channel)
{
ADC_t* adc_ptr = (ADC_t*)(adc << 4);
ADC_CH_t* adc_ch_ptr;
adc_ch_ptr = (ADC_CH_t*)((UINT8*)&(adc_ptr->CH0) + sizeof(ADC_CH_t) * channel);
...
}
Where the structure definition is given as:
typedef struct ADC_struct
{
...
register8_t reserved_0x1E;
register8_t reserved_0x1F;
ADC_CH_t CH0; /* ADC Channel 0 */
ADC_CH_t CH1; /* ADC Channel 1 */
ADC_CH_t CH2; /* ADC Channel 2 */
ADC_CH_t CH3; /* ADC Channel 3 */
} ADC_t;
With the pointer size being 2 bytes and UINT8
represented as a typedef unsigned char
. When linting the code, my linter reports back a warning
cast from UINT8* to ADC_CH_t* increases required alignment from 1 to 2 on the line
adc_ch_ptr = (ADC_CH_t*)((UINT8*)&(adc_ptr->CH0) + sizeof(ADC_CH_t) * channel);
The code is trying to calculate the correct offset into the struct for the channel pointer adc_ch_ptr
(where channel is between 0 and 3) It looks like a strict aliasing violation to me and I removed the cast from (UINT8*)
senselessly and it crashed the application.
Can anyone shed some light on how to correctly calculate the pointer to the correct channel without aliasing and padding/alignment issues?
Thanks