修复C代码编译报-Wmaybe-uninitialized的pwd未初始化警告
问题原因
这个警告是代码本身存在逻辑缺陷导致的,不是单纯的系统环境差异,你朋友的电脑上没出警告只是编译器版本/编译参数不同没检测出问题,不代表代码没有运行风险。
具体问题点有两个:
- 局部指针变量
pwd声明后没有初始化,只有在stat()调用成功的if分支里才会被赋值。一旦stat()调用失败(比如文件被临时删除、无目标文件读取权限),pwd会保留栈上的随机垃圾值,后续判断if (pwd != 0)的逻辑完全不可靠,甚至可能触发野指针访问导致程序崩溃。 - 循环里冗余调用了两次
stat(),第一次调用完全没有做返回值检查,如果stat()执行失败,my_stat结构体里的字段全是未初始化的垃圾值,后续读取文件大小、修改时间、UID的操作都会输出错误内容,甚至触发内存访问异常。
修改方案
- 声明
pwd时直接初始化为NULL,保证所有代码路径下它的值都是确定的,直接消除未初始化警告。 - 删除第一次无返回值检查的冗余
stat()调用,把所有依赖stat()返回结果的逻辑(获取用户信息、格式化时间、打印文件属性)全部放到stat()调用成功的分支内,避免调用失败时读取未初始化的结构体字段。
修正后的可直接编译运行的完整代码如下:
#include <stdio.h> #include <dirent.h> #include <sys/stat.h> #include <pwd.h> #include <time.h> #include <errno.h> #include <string.h> int list_dir(const char *dir) { struct dirent* cur_directory; struct stat my_stat; struct tm lt; // 声明时直接初始化为NULL,消除未定义值风险 struct passwd *pwd = NULL; DIR* directory = opendir(dir); if(directory == NULL) { printf("list_dir : %s : %s \n", dir, strerror(errno)); return 0; } printf("Directory : %s\n\n", dir); while( (cur_directory = readdir(directory)) ) { // 移除冗余stat调用,仅保留带返回值检查的一次调用 if (stat(cur_directory->d_name, &my_stat) == 0) { pwd = getpwuid(my_stat.st_uid); time_t t = my_stat.st_mtime; localtime_r(&t, <); char timebuf[80]; strftime(timebuf, sizeof(timebuf), "%c", <); if (pwd != NULL) { printf("%s \t %ld \t %s \t %s\n", pwd->pw_name, (long)my_stat.st_size, timebuf, cur_directory->d_name); } else { printf("%d \t %ld \t %s \t %s\n", my_stat.st_uid, (long)my_stat.st_size, timebuf, cur_directory->d_name); } } else { // stat调用失败时打印错误信息,方便排查问题 printf("access %s failed: %s\n", cur_directory->d_name, strerror(errno)); } } closedir(directory); return 0; } int main(int argc, char* argv[]){ if ( argc == 1 ) { return list_dir ( "." ); } else { int ret = 0; for (int i = 1; i < argc; i += 1 ) { if ( list_dir ( argv[i] ) != 0 ) { ret = 1; } } return ret; } }
补充说明
不同编译器、同一编译器的不同版本的控制流分析能力有差异,加上编译时开启的优化等级、警告参数不同,可能出现同一份代码在某台机器上不报警告、在另一台机器上报警告的情况。但只要编译器报了-Wmaybe-uninitialized,就说明代码存在可触发未定义行为的路径,必须修正,不能靠换编译环境绕过警告。
内容的提问来源于stack exchange,提问作者user17978223
相关产品推荐
相关产品推荐

