Я думаю, что скрытие определения структуры делает код более безопасным, поскольку вы применяете с помощью компилятора, к которому не может быть напрямую связан ни один из членов структуры. Недостатком является то, что пользователи не могут объявлять переменные типа структуры в стеке, потому что размер структуры неизвестен, а иногда желательно избегать использования malloc()
. Это может быть (с частичным успехом) решение с alloca(3)
, которое присутствует во всех основных реализациях libc, хотя эта функция не соответствует POSIX. Учитывая эти небольшие плюсы и минусы, может ли такой дизайн вообще считаться хорошим?Является ли хорошей практикой скрывать определение структуры в C?
В 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);
}
UPD: Обновленный вопрос о том, является явным, что идея используя alloca()
, должен иметь возможность объявлять структуру в стеке, но скрывать ее определение.
Более распространенный выбор - использовать что-то вроде 'foo_create' и' foo_destroy', что означает, что вы не раскрываете * каких-либо * деталей своей структуры и не можете делать более сложные вещи, например, хранить внутренние указатели 'malloc''d , Там очень мало ситуаций, когда вы * на самом деле * хотите использовать 'alloca', кроме, возможно, встроенных систем, где' malloc' и друзья супер ограничены. –
Если структура непрозрачна, было бы плохой дизайн, чтобы клиентский код нуждался в распределении или объявлении любых переменных этого типа, как показано в примере. Все экземпляры структуры должны поступать из самой библиотеки. – kaylum
'VLA []' разрешено? (C99)? Объявление символьного массива 'foo_size' (с использованием' alignas') может работать. Тем не менее, в gerneral, соглашайтесь с @kaylum – chux