零长度数组调用memcmp触发array-bounds错误,如何修正代码?
修复GCC编译零长度数组的
array-bounds错误 原始代码
#include "memory.h" #include "stdint.h" #define MOLECULE_API_DECORATOR MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0] = {}; int main(int argc, char *argv[]) { uint32_t size = sizeof(MolDefault_ByteOpt); const uint8_t *expected = MolDefault_ByteOpt; const uint8_t *actual = NULL; if (memcmp(actual, expected, size) != 0){ return 1; } return 0; }
编译错误信息
使用gcc -Werror -Wall main.c编译时出现以下错误:
main.c: In function ‘main’: main.c:8:5: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds] 8 | int main(int argc, char *argv[]) { | ^~~~ main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here 6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0] = {}; | ^~~~~~~~~~~~~~~~~~ main.c:10:31: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds] 10 | const uint8_t *expected = MolDefault_ByteOpt; | ^~~~~~~~~~~~~~~~~~ main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here 6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0] = {}; | ^~~~~~~~~~~~~~~~~~ main.c:8:5: error: offset ‘0’ outside bounds of constant string [-Werror=array-bounds] 8 | int main(int argc, char *argv[]) { | ^~~~ main.c:6:38: note: ‘MolDefault_ByteOpt’ declared here 6 | MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[0] = {}; | ^~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors
问题原因
零长度数组[0]属于GCC扩展特性,并非C标准的一部分。新版本GCC(如12.2.1)的-Wall会严格检测数组访问边界:零长度数组没有任何元素,尝试获取其地址或引用时,会触发array-bounds警告,而-Werror将警告转为错误导致编译失败。
修复方案
方案1:改用指针+显式长度定义
将零长度数组替换为指针和单独的长度常量,完全符合C标准,避免边界检测问题:
#include "memory.h" #include "stdint.h" #define MOLECULE_API_DECORATOR MOLECULE_API_DECORATOR const uint8_t *const MolDefault_ByteOpt = NULL; MOLECULE_API_DECORATOR const uint32_t MolDefault_ByteOpt_Size = 0; int main(int argc, char *argv[]) { uint32_t size = MolDefault_ByteOpt_Size; const uint8_t *expected = MolDefault_ByteOpt; const uint8_t *actual = NULL; // 长度为0时无需执行memcmp,直接判定为相等 if (size != 0 && memcmp(actual, expected, size) != 0) { return 1; } return 0; }
方案2:调整数组定义并优化比较逻辑
如果需要保留数组形式,可改用未指定长度的空数组,并在比较时跳过长度为0的情况:
#include "memory.h" #include "stdint.h" #define MOLECULE_API_DECORATOR MOLECULE_API_DECORATOR const uint8_t MolDefault_ByteOpt[] = {}; int main(int argc, char *argv[]) { uint32_t size = sizeof(MolDefault_ByteOpt); const uint8_t *expected = MolDefault_ByteOpt; const uint8_t *actual = NULL; // 长度为0时memcmp返回0,无需执行比较 if (size != 0 && memcmp(actual, expected, size) != 0) { return 1; } return 0; }
两种方案都能正常编译通过,且保留了原代码中对actual和expected的比较逻辑。
内容的提问来源于stack exchange,提问作者Eval EXEC
相关产品推荐
相关产品推荐

