是否可以手动检查 c 中的内存对齐?
Is it possible to manual check the memory alignment in c?
我使用内在函数,所以我需要使用内存对齐。
由于这个原因,我总是这样编码:
float* data = (float*) _mm_malloc(sizeof(float)*3, 64);
但在某些情况下,我有包含混合内容的数组。所以有些部分是对齐的,有些不是。
我尝试使用简单测试 data%64 == 0
但编译器抛出 error: expression must have integral type
。指针不支持模运算。
是否可以实现这样的功能:
// prototype
int testAlignment(void *pointer, int alignment);
float* data = (float*) _mm_malloc(sizeof(float)*3, 64);
testAlignment(data, 64); // true
testAlignment(data + 1, 64); // false
没有为指针定义提醒操作,但您可以将指针转换为整数。
((unsigned)data % 64) == 0
会成功的。
%
运算符需要 整数 个操作数。那么如何将指针转换为 integer?
Any pointer type may be converted to an integer type. ..., the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. C11 §6.3.2.3 5
考虑以下内容,将 float *
转换为 unsigned
可能会起作用,但它存在未定义行为 (UB) 的风险。
float* data = foo();
if ((unsigned)data % 64 == 0) puts("aligned 64");
我们可以做得更好吗?
A pointer to void
may be converted to or from a pointer to any object type. §6.3.2.3 1
The following type designates an unsigned integer type with the property that any valid pointer to void
can be converted to this type ... uintptr_t
...
These types are optional §7.20.1.4 1
是的,通过转换为 void*
然后转换为 uintptr_t
,代码避免了 UB 。 uintptr_t
仍然是 optional 类型。然而,自 C99 以来,它很少可用。
#include <stdint.h>
if ((uintptr_t)(void*)data % 64 == 0) puts("aligned 64");
我使用内在函数,所以我需要使用内存对齐。 由于这个原因,我总是这样编码:
float* data = (float*) _mm_malloc(sizeof(float)*3, 64);
但在某些情况下,我有包含混合内容的数组。所以有些部分是对齐的,有些不是。
我尝试使用简单测试 data%64 == 0
但编译器抛出 error: expression must have integral type
。指针不支持模运算。
是否可以实现这样的功能:
// prototype
int testAlignment(void *pointer, int alignment);
float* data = (float*) _mm_malloc(sizeof(float)*3, 64);
testAlignment(data, 64); // true
testAlignment(data + 1, 64); // false
没有为指针定义提醒操作,但您可以将指针转换为整数。
((unsigned)data % 64) == 0
会成功的。
%
运算符需要 整数 个操作数。那么如何将指针转换为 integer?
Any pointer type may be converted to an integer type. ..., the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. C11 §6.3.2.3 5
考虑以下内容,将 float *
转换为 unsigned
可能会起作用,但它存在未定义行为 (UB) 的风险。
float* data = foo();
if ((unsigned)data % 64 == 0) puts("aligned 64");
我们可以做得更好吗?
A pointer to
void
may be converted to or from a pointer to any object type. §6.3.2.3 1The following type designates an unsigned integer type with the property that any valid pointer to
void
can be converted to this type ...uintptr_t
... These types are optional §7.20.1.4 1
是的,通过转换为 void*
然后转换为 uintptr_t
,代码避免了 UB uintptr_t
仍然是 optional 类型。然而,自 C99 以来,它很少可用。
#include <stdint.h>
if ((uintptr_t)(void*)data % 64 == 0) puts("aligned 64");