GCC编译报错:DIR变量存储大小未知的原因与修复方法
编译错误原因与修复方案
问题复现
存在问题的函数代码如下:
#include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #define _ISDIR 1729 #define _ISFILE 431 #define _EXIST_ERR 611 #define _BUF_LEN 512 unsigned int fod(char*); unsigned int fod(char *name){ DIR check_dir; check_dir=opendir(name); int openf=open(name,O_RDONLY); if(check_dir!=NULL){ return _ISDIR; } if(openf!=-1){ return _ISFILE; } return _EXIST_ERR; }
使用gcc 12.1.1版本编译上述代码时,抛出如下编译错误:
copy.c:14:9: error: storage size of ‘check_dir’ isn’t known 14 | DIR check_dir; | ^~~~~~~~~
错误产生原因
- 直接原因:
DIR是POSIX定义的不完整类型,标准仅要求opendir()返回指向DIR类型的指针,不对外暴露DIR结构体的具体成员与内存大小,编译器无法为栈上定义的DIR check_dir变量计算所需分配的内存空间,因此触发存储大小未知的编译错误。 - 隐藏逻辑问题:原代码即使修正编译错误,还存在两个隐患:一是打开目录、文件成功后没有对应调用
closedir()、close()释放资源,会造成文件描述符泄漏;二是无论路径是否为目录都会先执行目录打开操作,再执行文件打开操作,产生无意义的系统调用开销。
修复方案
修复后的可正常编译运行的代码如下:
#include <stdio.h> #include <fcntl.h> #include <sys/stat.h> #include <sys/types.h> #include <stdlib.h> #include <string.h> #include <dirent.h> #include <unistd.h> #define _ISDIR 1729 #define _ISFILE 431 #define _EXIST_ERR 611 #define _BUF_LEN 512 unsigned int fod(char* name); unsigned int fod(char *name){ // 使用DIR*指针接收opendir返回值,禁止直接定义DIR类型的栈变量 DIR *check_dir = opendir(name); if (check_dir != NULL) { closedir(check_dir); // 判定为目录后立即关闭目录句柄 return _ISDIR; } int openf = open(name, O_RDONLY); if (openf != -1) { close(openf); // 判定为普通文件后立即关闭文件描述符 return _ISFILE; } return _EXIST_ERR; }
核心修改点:
- 将栈变量
DIR check_dir修改为DIR *check_dir指针类型,匹配opendir()的返回值类型,从根源解决不完整类型无法分配内存的编译错误。 - 补充
<unistd.h>头文件引入close()函数的正确声明,避免编译器隐式声明警告。 - 增加资源释放逻辑,所有成功打开的目录句柄、文件描述符在判定完成后立即关闭,避免资源泄漏。
- 调整执行逻辑:仅当目录打开失败时才尝试打开普通文件,减少不必要的系统调用。
内容的提问来源于stack exchange,提问作者dfmaaa1
相关产品推荐
相关产品推荐

