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

使用container_of时如何规避security.ArrayBound警告?

问题:使用container_of宏触发clang-tidy的security.ArrayBound警告

我编写了通过container_of宏从内部结构体指针获取父结构体指针的代码,但运行clang-tidy时触发了security.ArrayBound警告。

示例代码

#include <stdio.h>
#include <stddef.h>
#include <assert.h>

#define container_of(ptr, type, member) ({ \
    const void *__mptr = (void *)(ptr); \
    (type *)((char *)__mptr - offsetof(type, member)); \
})

/* 简单内部结构体 */
struct inner_data {
    int id;
    float value;
};

/* 包含内部结构体的容器结构体 */
struct container {
    double extra_value;
    char name[32];
    int count;
    struct inner_data data;  /* 嵌入式内部结构体 */
};

/* 操作内部结构体的函数 */
void update_data(struct inner_data *data, float new_value) {
    /* 使用container_of获取容器结构体指针 */
    struct container *parent = container_of(data, struct container, data);

    /* 更新容器结构体字段 */
    parent->extra_value = new_value * 2.0;
}

int main()
{
    struct container my_container;
    struct inner_data * mydata = &my_container.data;
    update_data(mydata, 200.0);
}

触发的警告信息

运行命令:clang-tidy-21 -checks=clang-analyzer-* test.c -- -std=c11 -O2

得到警告:

1 warning generated.
/tmp/test.c:31:13: warning: Out of bound access to memory preceding 'my_container.data' [clang-analyzer-security.ArrayBound]
   31 |     parent->extra_value = new_value * 2.0;
      |             ^
/tmp/test.c:38:5: note: Calling 'update_data'
   38 |     update_data(mydata, 200.0);
      |     ^~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/test.c:31:13: note: Access of 'my_container.data' at negative byte offset -44
   31 |     parent->extra_value = new_value * 2.0;
      |     ~~~~~~~~^~~~~~~~~~~

解决方法

这个警告属于clang静态分析器的误报,它无法识别container_of的合法指针偏移逻辑。可以通过以下几种方式处理:

1. 单位置抑制警告

在触发警告的代码行上方添加注释,让clang-tidy忽略该位置的特定警告:

void update_data(struct inner_data *data, float new_value) {
    struct container *parent = container_of(data, struct container, data);

    // NOLINTNEXTLINE(clang-analyzer-security.ArrayBound)
    parent->extra_value = new_value * 2.0;
}

2. 优化container_of宏写法

给宏添加类型兼容性检查,帮助分析器识别这是合法操作,同时提升代码安全性:

#define container_of(ptr, type, member) ({ \
    static_assert(__builtin_types_compatible_p(__typeof__(ptr), __typeof__(&((type *)0)->member)), \
                  "container_of: 指针类型不匹配"); \
    const typeof(((type *)0)->member) *__mptr = (ptr); \
    (type *)((char *)__mptr - offsetof(type, member)); \
})

这里的static_assert会在编译期检查传入的指针类型是否和结构体成员的指针类型匹配,避免错误使用宏,同时让分析器更容易理解宏的逻辑。

3. 全局排除该警告(不推荐)

如果多个位置出现此类误报,可以在clang-tidy命令中排除该检查:

clang-tidy-21 -checks=clang-analyzer-*,-clang-analyzer-security.ArrayBound test.c -- -std=c11 -O2

注意:这种方式会忽略所有security.ArrayBound类型的警告,可能错过真正的数组越界问题,仅在确认所有相关警告都是误报时使用。

内容的提问来源于stack exchange,提问作者shodanex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:57:24