![](/img/trans.png)
[英]gcc -Wall -Wuninitialized is not throwing warning for uninitialized variable
[英]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.
我很难理解为什么会出现此警告? Assert 将在变量为0
的情况下启动并立即返回,这意味着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.
这是它的基本结构(您可以在发布之前自己完成此简化):
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;
初始化 (附有解释原因的评论)。
它说可以使用未初始化的。 这意味着编译器不确定。 在它说未初始化使用的地方给出了不同的警告。
警告的目的是让你再看一遍代码,质疑自己。 如果您已经这样做并且确信编译器在这种情况下是错误的,那么您可以忽略该警告。
如果您不确定,请尝试查看编译器 output 的反汇编列表。
我建议的一件事是,标准库中的宏assert
有时会编译为错误检查代码,有时会编译为空,具体取决于编译器设置。 使用 assert 作为宏名称的一部分意味着类似的行为,因此请检查您的构建设置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.