【发布时间】:2017-01-27 15:51:22
【问题描述】:
我在 C 中有一个函数,它接受 uint8_t * 参数,它必须指向 32 位对齐的内存。是否可以在 C 或 C++ 或任何特定平台的宏中为参数添加一些修饰,以便编译器或链接器在构建时如果未按要求对齐会抛出错误?
这里的想法是我想保护该功能不被其他用户(或我在 6 个月内)不当使用。我知道如何对齐我想传递给它的东西。我想确保没有人可以将未对齐的东西传递给它。
基于this answer,我认为我的问题的答案是“否”,不可能在构建时强制执行,但它似乎是一个有用的功能,所以我想我会检查一下。我的解决方法是将assert((((size_t)ptr) % 4) == 0);放在函数中,这样至少我可以在调试时在运行时捕获它。
根据我的经验,如果您在许多嵌入式平台上将未对齐的 uint8_t* 转换为 uint32_t*,结果是不确定的,因此我不想指望最终会出现“正确”的结果。另外,这是在实时系统上使用的,因此速度变慢可能是不可接受的。
欢迎引用,如果有的话。
【问题讨论】:
-
确定不是XY问题? Intel 上的未对齐访问几乎是无惩罚的,而在严格对齐架构上它无论如何都会导致 SIGBUS。
-
您会如何期望在buld time 出现错误?这需要编译器做很多事情,如果我这样做
uint8_t* sneaky = (uint8_t*) 1; alignmentRequiringFunction(sneaky);会怎样?或者如果sneaky的值来自fgets()?至少向调用者表明您期望的一种解决方法是将参数设为uint32_t *,因为这意味着需要自然对齐。 -
@cp.engr 在我看来,链接器(而不是编译器)可以假设我在运行时执行相同的对齐检查。 如何?指针值在链接时通常是未知的。
-
由于平台显然非常具体,是否可以选择重新实现或包装
malloc和free以仅使用对齐的内存? -
据我所知,在 C++ 中可以全局重载
new和delete运算符。
标签: c++ c c-preprocessor memory-alignment