创建一个全局"null"结构以便在C程序中重用?

d11*_*wtq 1 c struct global objective-c

不知道我在这里做错了什么.我有一个通过我的程序大量使用的结构.

typedef struct _MyStruct {
  // ... handful of non-trivial fields ...
} MyStruct;
Run Code Online (Sandbox Code Playgroud)

我期望(读,打算)程序的很多部分返回其中一个结构,但是其中许多应该能够返回一个"null"结构,它是一个单例/全局结构.确切的用例是执行功能说"我找不到你要我回来的东西".

我假设这是一个简单的例子,在头文件中定义一个变量,并在.c文件中初始化它.

// MyStruct.h

// ... Snip ...

MyStruct NotFoundStruct;
Run Code Online (Sandbox Code Playgroud)

-

// MyStruct.c

NotFoundStruct.x = 0;
NotFoundStruct.y = 0;
// etc etc
Run Code Online (Sandbox Code Playgroud)

但编译器抱怨初始化不是常量.

因为我不关心这个全局实际在内存中引用的内容,所以我只关心所有内容都使用相同的全局,我只是尝试删除初始化并简单地将定义留在头文件中.

但是当我这样做时:

MyStruct thing = give_me_a_struct(some_input);
if (thing == NotFoundStruct) {
  // ... do something special
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨二进制运算符"=="(或"!=")的操作数无效.

如何定义诸如全局可重用(始终是相同的内存地址)结构?

Jam*_*lis 9

这不能直接回答你的问题,但它不适合评论......

如果你有一个可能需要返回某个函数或者什么都不返回的函数,那么有几个选项比返回"null struct"或"sentinel struct"更好,特别是因为结构在C中不相等.

一个选项是返回一个指针,这样你就可以实际返回NULL以表明你真的没有返回任何东西; 这有一个缺点,即具有重要的内存管理含义,即谁拥有指针?你是否必须在堆上创建一个尚未存在的对象才能执行此操作?

更好的选择是将指向结构的指针作为"out"参数,使用该指针存储实际结果,然后返回int指示成功或失败的状态代码(或者bool如果您有C99编译器则返回).这看起来像是这样的:

int give_me_a_struct(MyStruct*);

MyStruct result;
if (give_me_a_struct(&result)) {
    //  yay!  we got a result!
}
else {
    //  boo!  we didn't get a result!
}
Run Code Online (Sandbox Code Playgroud)

如果give_me_a_struct返回零,则表示它未找到结果result且未填充对象.如果它返回非零值,则表示它确实找到了结果并result填充了对象.