零长数组

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 
#include 
 
#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



你可能感兴趣的:(c/c++基础)