У меня есть небольшой модуль сокрытия данных, который выглядит так:
/** mydata.h */
struct _mystruct_t;
typedef struct _mystruct_t mystruct;
mystruct *newMystruct();
void freeMystruct( mystruct** p );
/** mydata.c */
#include "mydata.h"
struct _mystruct_t {
int64_t data1;
int16_t data2;
int16_t data3;
};
// ... related definitions ... //
По большей части, это то, что я хочу; несмотря на простоту, структура имеет строгие требования к согласованности, и я действительно не хочу предоставлять доступ к элементам данных.
Проблема в том, что в клиентском коде я хотел бы включить структуру в другую структуру, которую я хотел бы разместить в стеке. Прямо сейчас я прыгаю через обручи, чтобы освободить mystruct*
в каком-то клиентском коде. Поскольку а) mystruct довольно мала, и я действительно не думаю, что она станет большой в ближайшее время, и б) это не проблема, что клиентский код должен перекомпилироваться, если я когда-либо изменю mystruct, я хотел бы сделать размер mystruct общедоступным (то есть в шапке).
Две возможности, которые я рассмотрел:
/** mydata.h */
typedef struct {
// SERIOUSLY DON'T ACCESS THESE MEMBERS
int64_t data1;
int16_t data2;
int16_t data3;
} mystruct;
Я думаю, недостатки здесь говорят сами за себя.
OR
/** mydata.h */
#define SIZEOF_MYSTRUCT (sizeof(int64_t)+sizeof(int16_t)+sizeof(int16_t))
// everything else same as before...
/** mydata.c */
// same as before...
_Static_assert (SIZEOF_MYSTRUCT == sizeof(mystruct), "SIZEOF_MYSTRUCT is incorrect")
Конечно, это кажется неидеальным, так как мне нужно обновить это значение вручную, и я не знаю, может ли/как выравнивание структуры на самом деле привести к тому, что это будет неправильным (я думал о статическом утверждении при написании этого вопроса, он частично решает это беспокойство).
Является ли один из них предпочтительным? Или, что еще лучше, есть ли какой-то хитрый трюк, чтобы предоставить фактическое определение структуры в заголовке, а позже каким-то образом скрыть возможность доступа к членам?