CLion可运行的C代码在VS中报E0028错误:表达式需为常量值
解决VS编译报错E0028及代码隐藏问题
编译错误E0028的根源与解决
Linux下的GCC支持C99标准的变长数组(VLA),也就是char str[x];这种用变量定义数组长度的写法,但Windows的MSVC(Visual Studio默认C编译器)不支持C99变长数组,因此会抛出“表达式需为常量值”的错误。这里提供两种解决方式:
方法1:用动态内存分配替代(跨平台首选)
这是最通用的跨平台写法,通过malloc动态申请内存,用完后释放即可:
#include <stdlib.h> #include <ctype.h> #include <string.h> entry_t* find_entry( char* n ) { int x = strlen(n); // 分配内存时多留1位存字符串结束符'\0' char *str = malloc(x + 1); if (str == NULL) { // 必须检查内存分配是否成功 return NULL; } // 用已知的x作为循环上限,避免读取未初始化的str for (size_t i = 0; i < x; i++) { // 转成unsigned char,避免toupper处理负数值的未定义行为 str[i] = toupper((unsigned char)n[i]); } str[x] = '\0'; // 手动添加字符串结束符,否则strcmp会出错 n = str; // 直接让n指向str,&str会导致类型不匹配 entry_t* result = NULL; for (size_t i = 0; i < list_length; i++) { if (strcmp(n, name_list[i].name) == 0) { result = &name_list[i]; break; } } free(str); // 释放动态分配的内存 return result; // 没找到匹配项时返回NULL,避免未定义行为 }
方法2:开启MSVC的C99支持(仅限新版VS)
如果坚持使用变长数组,可以在VS中修改项目设置:
- 右键项目 → 属性 → C/C++ → 语言 → 选择“C99标准”
不过这种写法不具备跨平台性,不推荐。
代码中的其他隐藏问题
除了编译错误,原代码还有几个会导致崩溃或未定义行为的问题:
- 读取未初始化的数组:
strlen(str)时str刚声明,内部是随机垃圾值,strlen会越界读取直到遇到'\0',直接用之前获取的x作为循环上限即可。 - 类型不匹配赋值:
n = &str;中&str是指向数组的指针(类型char (*)[x]),而n是char*,类型不兼容,应改为n = str;(数组名会隐式转为指向首元素的指针)。 - 缺少默认返回值:循环结束后未找到匹配项时,函数没有返回值,会触发未定义行为,必须在最后添加
return NULL;。 - toupper参数风险:若
n中的char是有符号类型且值为负,传给toupper会导致未定义行为,因此要先转成unsigned char再传入。
内容的提问来源于stack exchange,提问作者Venox
相关产品推荐
相关产品推荐

