[英]A type for arbitrary memory in C
这是参考这个问题
接受的答案提到可以使用char
数组对任意内存池进行建模。
但是,对该已接受答案的评论之一指出
没有分配存储时间的char数组只能以字符类型作为别名。 换句话说,它不能也不应用作任意内存
这个对吗? 如果是这样,那么可以使用什么呢? 我想避免使用alloc
或任何特定的OS调用-所以我对这个问题持对称态度。
周围有不同的问题。 首先,如@Magisch的答案所示,相关问题是返回一个悬空指针,导致未定义行为和一般执行错误。
第二个与@ ^ *#(此处为检查)严格的别名规则相关。 当您将字符数组用作大缓冲区以从中分配任何类型时,如果您确保正确对齐,则普通编译器会生成正确的代码。 毕竟,这是他们必须实现malloc
, realloc
和free
例程的方式。 而且,由于它们是托管环境 (C标准库)的一部分,因此编译器开发人员还不足以禁止其使用。
但是C标准在这里更加严格。 您应该在此处阅读我对类似问题的答案,尤其是@EOF对它的评论:
您不能将声明为char []的对象的一部分打包为其他类型(字符类型除外)的对象,因为它们确实具有声明的类型...这意味着从技术上讲,您不能在纯C语言中实现malloc()
问题是对齐。 在具有对齐限制的处理器上, char
数组可能不会从适合于存储较大对象(例如int
或double
的地址开始。
为了安全起见,您需要确保char
数组对于任何类型都正确对齐。 如果您使用的是C11编译器,则可以像这样强制对齐
#include <stddef.h>
#include <stdalign.h>
_Alignas(max_align_t) char buffer[SIZE];
对于较旧的编译器, __attribute__((aligned(SIZE)))
可能是一个解决方案。 否则,您需要查找强制对齐的#pragma
。
而且,正如在各种注释/答案中所讨论的,您绝对应该使用-fno-strict-aliasing
选项禁用严格的别名优化。 如果该选项(或等效选项)不存在,则需要确定依赖于严格别名规则的优化级别,并且仅使用较低的优化级别。
我认为他指出的问题是,如果您静态分配一个char
类型的数组,然后使用像gcc这样的现代,类似于桌面的C编译器来编译您的库,则无法轻松地将该区域的内容转换为另一种类型。 因为这样编译器将基于指针别名执行优化并将所有事情搞砸,因此请参阅“严格的别名规则” 。
只需确保您的编译器不使用严格的别名就可以了。 例如,市场上没有一个普通的嵌入式系统编译器可以做到这一点。
使用gcc时,您将编译为-fno-strict-aliasing
。 始终为可能导致此类问题的代码启用警告可能会很有用-Wstrict-aliasing
。
附带说明一下,将uint8_t
用作泛型类型更有意义,因为与char
不同,它是完全明确的:它没有签名,并且大小是众所周知的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.