GCC 中允许使用零长数组(__GNUC__ >= 3)。
零长数组在有固定头部的可变对象上非常适用,我们可以根据对象的大小动态地去分配结构体的大小。
gui ftk里经常用的。在分配内存时,零长数组指向变长的PrivInfo。
FTK_ZALLOC(
sizeof
(FtkSource) +
sizeof
(PrivInfo))
#if __GNUC__ >= 3
#define ZERO_LEN_ARRAY 0
#else
#define ZERO_LEN_ARRAY 1
#endif
struct _FtkSource
{
FtkSourceGetFd get_fd;
FtkSourceCheck check;
FtkSourceDispatch dispatch;
FtkSourceDestroy destroy;
int ref;
int disable;
char priv[ZERO_LEN_ARRAY];
};
typedef struct _PrivInfo
{
FtkTimer action;
void* user_data;
size_t interval;
size_t next_time;
}PrivInfo;
FtkSource* ftk_source_timer_create(int interval, FtkTimer action, void* user_data)
{
FtkSource* thiz = NULL;
return_val_if_fail(interval > 0 && action != NULL, NULL);
thiz = (FtkSource*)FTK_ZALLOC(sizeof(FtkSource) + sizeof(PrivInfo));
if(thiz != NULL)
{
DECL_PRIV(thiz, priv);
//PrivInfo* priv = PrivInfo*(thiz->priv); //zlz comment
thiz->get_fd = ftk_source_timer_get_fd;
thiz->check = ftk_source_timer_check;
thiz->dispatch = ftk_source_timer_dispatch;
thiz->destroy = ftk_source_timer_destroy;
thiz->ref = 1;
priv->interval = interval;
priv->user_data = user_data;
priv->action = action;
ftk_source_timer_calc_timer(priv);
}
return thiz;
}
demo
#ifdef __cplusplus
extern "C"
{
#endif
#include <stdio.h>
#include <string.h>
#if __GNUC__ >= 3
#define ZERO_LEN_ARRAY 0
#else
#define ZERO_LEN_ARRAY 1
#endif
typedef struct taglcgi_msg_head
{
//MessageHead mh;
int is_return;
int result;
int reason;
char user[32];
char ipaddr[16];
//char priv[0];
}LCGI_MSG_HEAD, *PLCGI_MSG_HEAD;
typedef struct taglcgi_msg_head0
{
//MessageHead mh;
int is_return;
int result;
int reason;
char user[32];
char ipaddr[16];
char priv[0]; //不占空间,用的时候才占
}LCGI_MSG_HEAD0, *PLCGI_MSG_HEAD0;
typedef struct taglcgi_msg_head1
{
//MessageHead mh;
int is_return;
int result;
int reason;
char user[32];
char ipaddr[16];
char priv[1]; //大小/功能都等同于void* priv
}LCGI_MSG_HEAD1, *PLCGI_MSG_HEAD1;
typedef struct taglcgi_msg_head2
{
//MessageHead mh;
int is_return;
int result;
int reason;
char user[32];
char ipaddr[16];
void* priv; //大小/功能都等同于void* priv
}LCGI_MSG_HEAD2, *PLCGI_MSG_HEAD2;
int main(int argc,char* argv[])
{
printf("sizeof(LCGI_MSG_HEAD) len %d\n", sizeof(LCGI_MSG_HEAD));
printf("sizeof(LCGI_MSG_HEAD0) len %d\n", sizeof(LCGI_MSG_HEAD0));
printf("sizeof(LCGI_MSG_HEAD1) len %d\n", sizeof(LCGI_MSG_HEAD1));
printf("sizeof(LCGI_MSG_HEAD2) len %d\n", sizeof(LCGI_MSG_HEAD2));
char *p ="123";
//char const *p ="123";
p = "3214545";
//p[1] = 'd';
printf("p %s\n", p);
return 0;
}
#ifdef __cplusplus
}
#endif