Hello,
I'm using MCUXpresso (v11.6) on MKL33Z256 and I get a warning at compile time:
"array subscript 2 is outside array bounds of 'uint32_t[1]' {aka 'unsigned int[1]'} [-Warray-bounds]"
I try many solution but not working.
Bellow is my simplified code :
static boolean MyFunc(const uint8_t* FlashAddressPtr)
{
const uint8_t Header[] = {0xF1, 0xF1, 0x01, 0x00}; /* Magic Code + the number of Certificate file... */
uint32_t ListSize;
uint16_t ContentLen;
memcpy(&ListSize, (FlashAddressPtr + 4) , 4);
memcpy(&ContentLen, (FlashAddressPtr + 10) , 2);
I get the warning only on the second "memcpy" not on the first.
THis warnig appears ONLY with optimization -O3. Not in O2, or none...
Is somebody can help me to understand what is my problem?
Regards
已解决! 转到解答。
>>So It is an address value given by the linjer file corresponding to a memory specific defined zone...
No, not really. What you have here is a linker defined symbol, from which you can take the address (which is in fact the value of the virtual object). Actually it is not an object in the traditional sense, but a 'label'.
As you are using it as a pointer, I would expect that you would declare it as such, for example:
extern void *__base_MQTT_CERT_0;
I hope this helps?
Erich
>>So It is an address value given by the linjer file corresponding to a memory specific defined zone...
No, not really. What you have here is a linker defined symbol, from which you can take the address (which is in fact the value of the virtual object). Actually it is not an object in the traditional sense, but a 'label'.
As you are using it as a pointer, I would expect that you would declare it as such, for example:
extern void *__base_MQTT_CERT_0;
I hope this helps?
Erich
In the same post, It still some other warning I will like to remove!
Can I ask you some help?
1) conversion from 'int' to 'uint8_t' {aka 'unsigned char'} may change value [-Wconversion]
static uint8_t DV_Rtc_iDayOfWeek(rtc_datetime_t DateTime)
{
DateTime.day = (uint8_t)(DateTime.day += (uint8_t)DateTime.month < 3 ? DateTime.year-- : DateTime.year - 2, 23 * DateTime.month / 9 + DateTime.day + 4 + DateTime.year / 4 - DateTime.year / 100 + DateTime.year / 400) % 7;
return (DateTime.day);
}
Warning is on the lime "DateTime.day = ..."
I get the "formula" directly on wikipedia. I'm not so familiar with this style of "If, elsif.."
2)conversion from 'uint8_t' {aka 'unsigned char'} to 'unsigned char:4' may change value [-Wconversion]
Warnig is on this line
In .h:
typedef struct
{
uint16_t ChannelSelect: 4;
uint16_t BufferMode: 1;
uint16_t RefDetect: 1;
uint16_t RefSelect: 2;
uint16_t GainSelect: 3;
uint16_t Boost: 1;
uint16_t UnipolarBipolar: 1;
uint16_t BurnoutCurrent: 1;
uint16_t VBIAS: 2;
} tCT_AD7795_ConfigurationRegisterBits;
typedef union
{
tCT_AD7795_ConfigurationRegisterBits Bits;
uint16_t Data;
} tCT_AD7795_ConfigurationRegister;
typedef struct
{
uint8_t ChannelSelect;
uint8_t BufferMode;
uint8_t RefDetect;
uint8_t RefSelect;
uint8_t GainSelect;
int16_t NumericalGain;
uint8_t Boost;
uint8_t UnipolarBipolar;
uint8_t BurnoutCurrent;
uint8_t VBIAS;
boolean ErrorGenerateReset;
boolean CheckErrorMoveToFast;
int32_t DefaultValue;
tCT_AD7795_ThermocoupleType ThermoType;
} tCT_AD7795_ChannelCfg;
...
In .c
tCT_AD7795_ConfigurationRegister CT_AD7795_iConfigurationRegister[CT_AD7795_NB_CHANNEL];
tCT_AD7795_ChannelCfg CT_AD7795_ChannelCfg[CT_AD7795_NB_CHANNEL] =
{
/* CT_AD7795_CHANNEL0 : Configured to measure AIN1 */
{
/* ChannelSelect */ CT_AD7795_CONFIG_CHANNEL_AIN1,
/* BufferMode */ CT_AD7795_CONFIG_BUF_ENABLE,
/* RefDetect */ CT_AD7795_CONFIG_REFDET_DISABLE,
/* RefSelect */ CT_AD7795_CONFIG_REFSEL_INTERNAL,
/* GainSelect */ CT_AD7795_CONFIG_GAIN_16, /* If change here, change NumericalGain */
/* NumericalGain */ 16, /* If change here, change GainSelect */
/* Boost */ CT_AD7795_CONFIG_BOOST_ENABLE,
/* UnipolarBipolar */ CT_AD7795_CONFIG_UB_BIPOLAR,
/* BurnoutCurrent */ CT_AD7795_CONFIG_BO_DISABLE,
/* VBIAS */ CT_AD7795_CONFIG_VBIAS_AIN1,
/* ErrorGenerateReset */ TRUE,
/* CheckErrorMoveToFast */ FALSE,
/* DefaultValue */ 0,
/* ThermoType */ CT_AD7795_THEMROCOUPLE_TYPE_K
},
....
void MyFunc(...)
{
CT_AD7795_iConfigurationRegister[ChannelId].Bits.ChannelSelect = CT_AD7795_ChannelCfg[ChannelId].ChannelSelect; /* !!!! Warning on this line */
...}
I understand I try to "cast" byte (8bit) to a bitfield (ie 4 or 2 or 5 bits).
In my opinion, the code run correclty, but it should be great if the warning was controlled and removed.
What can I change to remove it? I have not idea!
Thank
Hi,
For the point 1, it should missed a cast. But with the "compressed form", it is not easy to see where it is.
So I used another method:
static uint8_t DV_Rtc_iDayOfWeek(rtc_datetime_t DateTime)
{
/* https://fr.wikibooks.org/wiki/Curiosit%C3%A9s_math%C3%A9matiques/Trouver_le_jour_de_la_semaine_avec_une_date_donn%C3%A9e */
int16_t c;
int16_t a;
int16_t m;
int16_t Result;
c = (int16_t)(14 - DateTime.month) / 12;
a = (int16_t)DateTime.year - c;
m = (int16_t)(DateTime.month + (12 * c) - 2);
Result = (int16_t)( DateTime.day + a + (a / 4) - (a / 100) + (a / 400) + (31 * m) / 12 ) % 7;
return ((uint8_t)Result);
}
Stay the affectation of uint16_t:x from an uint8_t... I looked for this problem, it seem a recurent unsolved problem.
Thank for reply.
My call is:
extern uint32_t __base_MQTT_CERT_0;
main()
{
...
MyFunc((uint8_t*)&__base_MQTT_CERT_0);
..
}
Linker file:
...
__base_MQTT_CERT_0 = 0x3dc00 ; /* MQTT_CERT_0 */
...
MCUXpresso config:
So It is an address value given by the linjer file corresponding to a memory specific defined zone...
How can I resolve this warning?
The problem is with 'FlashAddressPtr': you are passing the address of an object to your MyFunc with FlashAddressPtr which points to an object which is not large enough. So a classic 'array out-of-bounds' programming error.
You only get the warning with higher optimizations, because here the compiler does constant propagation and variable analysis cross function calls.
So I recommend you check all calls to MyFunc() and check if you have passed an object of adequate size passed.
To illustrate the case, consider following code:
static bool MyFunc(const uint8_t* FlashAddressPtr)
{
// const uint8_t Header[] = {0xF1, 0xF1, 0x01, 0x00}; /* Magic Code + the number of Certificate file... */
uint32_t ListSize;
uint16_t ContentLen;
memcpy(&ListSize, (FlashAddressPtr + 4) , 4);
memcpy(&ContentLen, (FlashAddressPtr + 10) , 2);
return false;
}
static const uint32_t var = 0x10;
int main(void) {
(void)MyFunc((uint8_t *)&var);
Here you pass the address of an object to your function, which is not large enough for your (FlashAddressPtr + 10): your object has to be at least 10+2 bytes large.
I hope this helps?
Erich