在C中隐藏结构定义是一个好习惯吗?

Ale*_*ets 8 c struct memory-management alloca

我认为隐藏结构定义会使代码更安全,因为您在编译器的帮助下强制执行,不能直接访问结构的任何成员.缺点是用户无法在堆栈上声明结构类型的变量,因为结构的大小未知,有时需要避免使用malloc().这可以(部分成功)解决,alloca(3)所有主要的libc实现都存在,尽管此函数不符合POSIX.鉴于这种优点和缺点,这样的设计一般可以认为好吗?

lib.h:

struct foo;
extern size_t foo_size;
int foo_get_bar (struct foo *);
Run Code Online (Sandbox Code Playgroud)

lib.c:

struct foo {
  int bar;
};

size_t foo_size = sizeof foo;

int foo_get_bar (struct foo *foo)
{
  return foo->bar;
}
Run Code Online (Sandbox Code Playgroud)

example.c:

#include "lib.h"

int bar(void) {
  struct foo *foo = alloca (foo_size);
  foo_init (foo);
  return foo_get_bar (foo);
}
Run Code Online (Sandbox Code Playgroud)

UPD:更新了问题,明确指出使用的思想alloca()是能够在堆栈上声明结构但隐藏其定义.

chu*_*ica 3

是的,隐藏数据是一个很好的做法。

\n

作为该模式的替代方案alloca(foo_size);,可以声明一个对齐的字符数组并执行指针转换。不过,指针转换并不完全可移植。如果大小是由变量而不是编译时常量定义的,则字符数组需要是 VLA:

\n
extern size_t size;\n\nstruct sfoo;\n\n#include <stddef.h>\n\nint main(void) {\n  unsigned char _Alignas (max_align_t) cptr[size];\n  // or unsigned char _Alignas (_Complex  long double) cptr[size];  // some widest type\n  struct sfoo *sfooptr = (struct sfoo *) cptr;\n  ...\n
Run Code Online (Sandbox Code Playgroud)\n

如果 VLA 不需要或不可用,请将大小声明为常量 ( #define foo_N 100),保证其大小至少满足需要。

\n