C中可堆栈的不透明类型
在设计C接口时,通常仅将用户程序中需要知道的公共接口(.h).
因此,例如,如果用户程序不需要知道结构的内部组件应该保持隐藏.这是一个很好的做法,因为结构的内容和行为在将来会发生变化,而不影响界面. 实现这一目标的一个很好的方法是使用不完整的类型. typedef struct foo opaqueType; 现在可以构建一个仅使用opaqueType指针的界面,而不需要用户程序来了解struct foo的内部工作. 但是有时,可能需要静态地分配这样的结构,通常在堆栈上,用于性能和内存分片问题.显然,在上面的构造中,opaqueType是不完整的,所以它的大小是未知的,所以它不能被静态分配. 一个工作是分配一个“shell类型”,如: typedef struct {int faketable [8]; } opaqueType; 以上构造强制大小和对齐,但不会更深入地描述结构真正包含什么.所以它符合保持类型“不透明”的目标. 它主要工作.但是在一种情况(GCC 4.4)中,编译器抱怨说它破坏了严格的别名,并且生成了错误的二进制文件. 现在,我已经读了很多有关严格混叠的事情,所以我想我现在明白了什么意思. 问题是:有没有办法定义一个不透明的类型,可以在堆栈上分配,而不会破坏严格的别名规则? 请注意,我尝试了union method described in this excellent article,但仍然产生相同的警告. 还要注意,视觉,cl ang和gcc 4.6及更高版本不要抱怨并且工作正常. 信息补充: 根据测试,问题只发生在以下情况: >私人和公共类型不同.我将公共类型转换为.c文件中的私有类型.如果他们是同一个联盟的一部分,这并不重要.公共类型包含char也没关系. 最后,我的目标是C90.也许C99如果真的没有选择. 解决方法
您可以强制使用max_align_t进行对齐,您可以使用char数组来避免严格的别名问题,因为char被明确允许别名为任何其他类型.
沿着以下方向的东西: #include <stdint.h> struct opaque { union { max_align_t a; char b[32]; // or whatever size you need. } u; }; 如果要支持没有max_align_t的编译器,或者如果您知道实际类型的对齐要求,则可以使用任何其他类型的联合成员. 更新:如果您正在定位C11,那么您也可以使用alignas(): #include <stdint.h> #include <stdalign.h> struct opaque { alignas(max_align_t) char b[32]; }; 当然,您可以用您认为合适的任何类型替换max_align_t.甚至一个整数. 更新#2: 那么在图书馆中使用这种类型的东西就是这样的: void public_function(struct opaque *po) { struct private *pp = (struct private *)po->b; //use pp->... } 这样,由于您是对char指针进行打字,您不会违反严格的别名规则. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |