☰
  • 首页
  • 规则分类
  • 项目介绍
search
•••

避免向对齐要求更严格的指针转换

12.13 ID_stricterAlignedCast
目录 › next › previous

访问不符合对齐要求的数据会导致标准未定义的行为。

对象的存储地址与其占用空间的长度相关,如变量的地址往往是其长度的整数倍,这种机制称为“内存对齐”,可提高处理器访问数据的效率,如果对象的地址不符合这种要求,访问对象的效率就会降低,在某些平台上甚至会崩溃,详见“unaligned access”。

每种对象类型都有一个“对齐要求(alignment requirement)”,一般来说占用空间越大的类型,对齐要求越严格,如 char 对象可以存储在任意地址,而 int 对象的地址只应是 sizeof(int) 的整数倍,所以解引用由 char 指针转换成的 int 指针很可能会造成“unaligned access”。

示例:

void foo(unsigned char* p) {
    char c = *(char*)p;            // Compliant
    long n = *(long*)(p + 1);      // Non-compliant
    ....
}

二进制数据转向结构化数据时,这种问题较为常见,例中 p + 1 与 long 型变量的对齐要求不同,不应直接转换。

应改为:

void foo(unsigned char* p) {
    char c = *(char*)p;            // Compliant
    long n;
    memcpy(&n, p + 1, sizeof(n));  // Compliant
    ....
}

用 memcpy 等函数将低对齐要求的数据复制到高对齐要求的对象中,是避免相关问题的通用模式。

例外:

alignas(long) short a[32];
long* p = (long*)a;          // Compliant

如果源类型的对齐声明与目标类型相符可不受本规则限制。另外,malloc、calloc 等函数的返回值已具备通用对齐要求,也不受本规则限制。

相关

ID_castNoInheritance

依据

ISO/IEC 9899:1999 6.3.2.3(7)-undefined ISO/IEC 9899:2011 6.3.2.3(7)-undefined

参考

SEI CERT EXP36-C
Copyright©2024 360 Security Technology Inc., Licensed under the Apache-2.0 license.