This is the code that generates warning: 'res' may be used uninitialized in this function [-Wmaybe-uninitialized]
lwdtcr_t
lwdtc_cron_parse_multi(lwdtc_cron_ctx_t* cron_ctx, const char** cron_strs, size_t ctx_len, size_t* fail_index) {
lwdtcr_t res;
ASSERT_PARAM(cron_ctx != NULL);
ASSERT_PARAM(cron_strs != NULL);
ASSERT_PARAM(ctx_len > 0);
/* Parse all input strings, each to its own cron context structure */
for (size_t i = 0; i < ctx_len; ++i) {
if ((res = lwdtc_cron_parse_with_len(&cron_ctx[i], cron_strs[i], strlen(cron_strs[i]))) != lwdtcOK) {
if (fail_index != NULL) {
*fail_index = i;
}
break;
}
}
return res;
}
Assert param macro is defined as
#define ASSERT_PARAM(c) if (!(c)) { return lwdtcERRPAR; }
/* Footprint of function being called inside is */
lwdtcr_t
lwdtc_cron_parse_with_len(lwdtc_cron_ctx_t* ctx, const char* cron_str, size_t cron_str_len)
Compiler
arm-none-eabi-gcc 10.3.1 20210824 (release)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I am having hard time to understand why this warning? Assert will kick-in in case variable is 0
and return immediately, meaning for
loop will always execute at least one round - if it gets to that point of course - meaning res
will be initialized at return statement.
There must be a optimization trick - but I'm not aware of at least - any clue?
lwdtcr_t
is simple enumeration.
Run code from here: https://godbolt.org/z/9E1xdv4dc
Removing '-Og' from flags magically works without any error
#include <string.h>
#include <time.h>
typedef enum {
lwdtcOK = 0x00, /*!< Everything is OK */
lwdtcERR, /*!< Generic error */
lwdtcERRPAR, /*!< Invalid parameter passed to a function */
lwdtcERRTOKEN, /*!< Token value is not valid */
} lwdtcr_t;
typedef struct {
uint32_t flags; /*!< List of all sort of flags for internal use */
} lwdtc_cron_ctx_t;
lwdtcr_t lwdtc_cron_parse_with_len(lwdtc_cron_ctx_t* ctx, const char* cron_str, size_t cron_str_len);
#define ASSERT_PARAM(c) if (!(c)) { return lwdtcERRPAR; }
lwdtcr_t
lwdtc_cron_parse_multi(lwdtc_cron_ctx_t* cron_ctx, const char** cron_strs, size_t ctx_len) {
lwdtcr_t res;
ASSERT_PARAM(cron_ctx != NULL);
ASSERT_PARAM(cron_strs != NULL);
ASSERT_PARAM(ctx_len > 0);
/* Parse all input strings, each to its own cron context structure */
for (size_t i = 0; i < ctx_len; ++i) {
res = lwdtc_cron_parse_with_len(&cron_ctx[i], cron_strs[i], strlen(cron_strs[i]));
}
return res;
}
With flags -Wall -Werror -Wextra -Og
And compiler
arm-none-eabi-gcc 10.3.1 20210824 (release)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Here it is, in its bare bones (you could have done this simplification yourself before posting):
int f (unsigned int len) {
int res;
if (len == 0) return 99;
for (unsigned int i = 0; i < len; ++i)
res = i;
return res;
}
This produces a similar warning.
But if you replace res = i
with res = 99
, the warning goes away. So it looks like a case of the compiler just not being infinitely clever. It's not worth spending much time on such cases; the simplest fix is to initialise with int res = 0;
(with a comment explaining why).