正确标头的 C 结构定义问题

jin*_*ter 2 c header-files

请原谅我的啰嗦。

这就是我喜欢为在模块中声明用户函数而创建的标头的方式。

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

chu*_*ica 6

信息隐藏是一个崇高的目标,但有时却很痛苦。

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细节。

  • @jinTgreater我尝试过“unions”、固定大小的缓冲区、“static_asserts”等技巧,只是为了返回:至少信任用户一点。 (2认同)