【发布时间】:2021-10-15 06:20:30
【问题描述】:
运行 clang-tidy 时,我在访问数组地址时收到警告:
src/main.cpp:10:9: warning: Assigned value is garbage or undefined [clang-analyzer-core.uninitialized.Assign]
sum += *(addr++);
^
代码是从一个更复杂的示例中剥离出来的(完整的校验和实现 - 取自 RFC1071 - 并使用结构而不是数组):
#include <iostream>
#include <cstring>
static uint16_t csum(void* buffer, size_t size)
{
uint32_t sum = 0;
auto *addr = static_cast<uint16_t *>(buffer);
while( size > 1 ) {
/* This is the inner loop */
sum += *(addr++);
size -= sizeof(*addr);
}
return static_cast<uint16_t>(~sum);
}
int main (int argc, char* argv[])
{
uint32_t test[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
//memset(&test, 0, sizeof(test));
uint16_t sum = csum(test, sizeof(test));
std::cout << argc << " " << argv[0] << " " << sum << " " << sizeof(test) << std::endl;
}
clang-tidy 在数组的类型为 uint32_t 或 uint64_t(或使用任何自定义打包结构)时显示此 value is garbage or undefined,但在 uint16_t 或 uint8_t 时不显示 - 一些对齐问题?
但至少对我来说更令人惊讶 - 在取消注释 memset 时,uint32_t、uint64_t 或任何自定义打包结构不会显示警告 - 为什么?之前没有正确初始化吗?我是否遇到了一些没有正确定义 C/C++ 的区域?
或者clang-tidy 会分析csum 的每一个用法——还有那些buffer 的大小与size 变量不匹配的用法?
【问题讨论】:
-
如果您将 1 字节对齐的指针输入到转换为
uint16_t的指针中,则应该会出现对齐问题。您必须通过memcpy将其转换为临时的 - 不要担心性能,编译器会消除它并将其读取为“哦,数据可能未对齐”。 -
即使您确实传递了类似
struct { uint32_t; uint8_t; }的内容,由于未定义的填充字节,警告仍然有效。 -
我最初使用了一个只有 uint16_t 和 uint8_t 的结构并使用了
__attribute__((packed))- 并得到了同样的警告。但也许这个属性没有被 clang-tidy 检查。
标签: c++ c++11 clang-tidy