请原谅我的啰嗦。
这就是我喜欢为在模块中声明用户函数而创建的标头的方式。
struct Object;
void function( struct Object * , ... );
Run Code Online (Sandbox Code Playgroud)
这只是为了使模块的用户不会有一个混乱的头文件,其中包含结构中使用的所有内容。
.c 文件具有结构定义。让我们在这个主结构中拥有结构。
struct Object {
int item;
struct Component component;
};
Run Code Online (Sandbox Code Playgroud)
让我们想在用户定义的结构中使用这个模块对象。说:
#include "module.h" /*declarations*/
...
struct UserItem {
int something;
...
struct Object object;
} userThing;
Run Code Online (Sandbox Code Playgroud)
这是我的 C 预处理问题。
这会导致一个问题。编译时,struct Object 的大小尚未定义,因此无法定义 struct UserItem 的大小,编译失败error: field 'object' has incomplete type
现在有什么办法补救吗??显然,可以使用结构指针,但这会使用动态内存分配来增加结构初始化的烦人步骤。对于结构定义有一个单独的头怎么样?好的,但这意味着结构符号名称现在与 struct Component 等名称混杂在一起。用户还必须包含此头文件以及主模块头文件。在我看来,这并不是一个好的解决方案。也许甚至做类似的事情struct Object { uint8_t component_mem[SIZE]; };
我唯一的想法是在编译过程中采取一个步骤,在其中对结构定义进行全局预处理,以便找到所有大小。我相信这必须在链接阶段完成,因为取消引用结构指针?
如果我犯了错误或者已经存在一个很好的解决方案,请告诉我。
类似的 stackoverflow 页面:1
信息隐藏是一个崇高的目标,但有时却很痛苦。
C只是不支持OP的目标,struct UserItem
通过公共文件了解内部结构,但不使用它们。
我见过的最好的就是警告。
将完整定义移至 .h 文件
// Object.h
/*
I know you may be tempted to access these struct members, but **DO NOT USE THEM**.
They are only here for sizing purposes and zero initialization.
Only Object support function should access members.
*/
struct Component {
int SecretDecoderRing;
double magic_number;
char psword[42];
};
struct Object {
int item;
struct Component component;
};
void Object_function1( struct Object * , ... );
void Object_function2( struct Object * , ... );
Run Code Online (Sandbox Code Playgroud)
struct Component
定义、struct Object
定义和警告可以存在于 Object.h 包含的单独的 Object_xxx.h 文件中,以实现适度的隐藏。然而,包含 Object.h 最终仍然会暴露这些struct
细节。