GCC for ARM 报告警告 - 潜在的未初始化变量
GCC for ARM reports warning - potential uninitialized variable
这是生成警告的代码:'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;
}
断言参数宏定义为
#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)
编译器
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.
我很难理解为什么会出现此警告?如果变量立即为 0
和 return,则断言将启动,这意味着 for
循环将始终执行至少一轮 - 当然如果它到达那个点 - 意味着 res
将在 return 语句处初始化。
一定有优化技巧 - 但我至少不知道 - 有什么线索吗?
lwdtcr_t
是简单枚举。
如何重现
运行 代码来自这里:https://godbolt.org/z/9E1xdv4dc
从标志中删除“-Og”神奇地工作,没有任何错误
最小示例
#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;
}
有旗帜-Wall -Werror -Wextra -Og
和编译器
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.
它说 可能 使用未初始化。这意味着编译器不确定。有一个不同的警告,它说 is used uninitialized.
警告的目的是让你再看一遍代码,质疑自己。如果您已经这样做并且确信编译器在这种情况下是错误的,那么您可以忽略警告。
如果您不确定,请尝试查看编译器输出的反汇编列表。
我建议的一件事是,标准库中的宏 assert
有时会编译为错误检查代码,有时会编译为空,具体取决于编译器设置。使用断言作为宏名称的一部分意味着类似的行为,因此请检查您的构建设置。
这就是它的基本结构(您可以在发布之前自行完成此简化):
int f (unsigned int len) {
int res;
if (len == 0) return 99;
for (unsigned int i = 0; i < len; ++i)
res = i;
return res;
}
这会产生类似的警告。
但是如果您将 res = i
替换为 res = 99
,警告就会消失。所以它看起来像是编译器不是无限聪明的情况。在这种情况下花太多时间是不值得的;最简单的修复方法是使用 int res = 0;
进行初始化(并附上解释原因的注释)。
这是生成警告的代码:'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;
}
断言参数宏定义为
#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)
编译器
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.
我很难理解为什么会出现此警告?如果变量立即为 0
和 return,则断言将启动,这意味着 for
循环将始终执行至少一轮 - 当然如果它到达那个点 - 意味着 res
将在 return 语句处初始化。
一定有优化技巧 - 但我至少不知道 - 有什么线索吗?
lwdtcr_t
是简单枚举。
如何重现
运行 代码来自这里:https://godbolt.org/z/9E1xdv4dc
从标志中删除“-Og”神奇地工作,没有任何错误
最小示例
#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;
}
有旗帜-Wall -Werror -Wextra -Og
和编译器
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.
它说 可能 使用未初始化。这意味着编译器不确定。有一个不同的警告,它说 is used uninitialized.
警告的目的是让你再看一遍代码,质疑自己。如果您已经这样做并且确信编译器在这种情况下是错误的,那么您可以忽略警告。
如果您不确定,请尝试查看编译器输出的反汇编列表。
我建议的一件事是,标准库中的宏 assert
有时会编译为错误检查代码,有时会编译为空,具体取决于编译器设置。使用断言作为宏名称的一部分意味着类似的行为,因此请检查您的构建设置。
这就是它的基本结构(您可以在发布之前自行完成此简化):
int f (unsigned int len) {
int res;
if (len == 0) return 99;
for (unsigned int i = 0; i < len; ++i)
res = i;
return res;
}
这会产生类似的警告。
但是如果您将 res = i
替换为 res = 99
,警告就会消失。所以它看起来像是编译器不是无限聪明的情况。在这种情况下花太多时间是不值得的;最简单的修复方法是使用 int res = 0;
进行初始化(并附上解释原因的注释)。