You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

零长度数组调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 17:11:10