【发布时间】:2016-03-21 21:44:32
【问题描述】:
在我看来,在 C 中隐藏结构的定义通常会使代码更安全,因为您在编译器的帮助下强制要求结构的任何成员都不能被直接访问。
但是,它有一个缺点,即结构的用户无法声明其类型的变量以放入堆栈,因为结构的大小以这种方式变得不可用(因此,用户必须求助于通过malloc() 在堆上分配,即使它是不可取的)。
这可以(部分)通过所有主要 libc 实现中存在的 alloca(3) 函数解决,即使它是 does not conform to POSIX。
考虑到这些优点和缺点,这样的设计总体上可以认为是好的吗?
在lib.h:
struct foo;
extern size_t foo_size;
int foo_get_bar(struct foo *);
在lib.c:
struct foo {
int bar;
};
size_t foo_size = sizeof foo;
int foo_get_bar(struct foo *foo)
{
return foo->bar;
}
在example.c:
#include "lib.h"
int bar(void)
{
struct foo *foo = alloca(foo_size);
foo_init(foo);
return foo_get_bar(foo);
}
【问题讨论】:
-
更常见的选择是使用
foo_create和foo_destroy之类的东西,这意味着您不会暴露结构的任何细节,并且可以做更高级的操作比如在内部存储malloc'd 指针。您实际上想要使用alloca的情况很少见,除了malloc和朋友非常有限的嵌入式系统。 -
如果结构是不透明的,那么让客户端代码需要分配或声明该类型的任何变量(如示例中所示)将是糟糕的设计。结构的所有实例都应该来自库本身。
-
VLA[]允许吗? (C99)?声明foo_size的字符数组(使用alignas)可能有效。然而,总的来说,同意@kaylum -
@chqrlie,是的,我在发表评论后不久就看到了,然后在您的回复到达这里之前删除了评论。
-
一旦您获得了符合您目标的候选解决方案,请将其清理、简化并尝试在codereview.stackexchange.com 上发布以获取更多反馈。准备好接受一些强烈的反馈。
标签: c memory-management struct alloca