![](/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.