这个问题与遵循 MISRAC:2012 指南的 ISO C99 编码有关。
我正在寻找有关 Dir 4.8 “如果指向结构或联合的指针从未在翻译单元中取消引用,则应隐藏对象的实现”以及 Dir 4.12 “不应使用动态内存分配”的指导。
在 C 中实现抽象数据类型时,通常使用句柄来引用 ADT,句柄是指向描述 ADT 内部状态的结构的指针。这可以使用 Dir 4.8 中的不透明指针来完成,其好处是内部细节对用户保持隐藏。
通常这些 ADT 中可能存在多个,因此必须有一种方法来创建多个句柄。这可以通过在初始化函数中为句柄引用的内部细节分配内存来解决,但是在 Dir 4.12 下这是不允许的。
另一种选择是初始化例程接收指向用户提供的静态分配句柄的指针,但是,这不能使用不透明指针来完成。
我在下面说明问题。
Module.h
struct module;
typedef struct module module_t; /* Module handle is only available to the world as an incomplete type. This allows us to satisfy MISRAC 2012 Dir 4.8.*/
Module.c
#include "module.h"
struct module
{
uint8_t value;
};
module_t* module_get_a_handle(void)
{
return (module_t*)malloc(sizeof(struct module)); /* MISRAC 2012 Dir 4.12 disallows dynamic memory allocation.*/
}
User.c
#include "module.h"
module_t* module_handle;
module_handle = module_get_a_handle();
这个问题也描述了这个问题 Static allocation of opaque data types,但是没有针对 MISRAC:2012 指南进行讨论。
所描述的一种解决方案是使用静态分配的句柄池,这些句柄池可供客户端代码使用。这个解决方案似乎在技术上是合规的;但是,这里似乎仍然存在动态内存分配的概念。我认为尽管句柄是静态分配的,但编译器无法在编译期间确定是否有足够的句柄可供软件正常运行。
我对这个问题的解决方案是围绕 Dir 4.8 编写一个偏差,并使用非透明指针和强大的命名约定,让用户清楚地知道 ADT 的内部细节不得更改。
我很好奇是否存在满足 Dir 4.8 和 Dir 4.12 且不违反任何其他 MISRAC:2012 规则的公认方法来解决此问题。任何意见将不胜感激。