Flexible array member (c99) inside a structure

我是研究僧i 提交于 2019-12-31 04:14:09

问题


I've being using this code a while now, and it works fine, but it gave me some headache to implement it. It uses Flexible Array Member (FAM) aka Struct Hack. Now that C99 has the possibility of using Variable Length Array (VLA), I wonder how can I take advantage in this piece?

typedef struct nO
{
    int oper;              /* some operator */
    int nops;              /* number of args */
    struct nO *ptn[1];     /* expansible array <=== HERE */
} nodoOper;

nodoOper *operator(int o, int n, ...)
{
    va_list ap;
    nodoOper *tn;
    size_t tam;
    int i;

    tam = sizeof(nodoOper) + (n - 1) * sizeof(nodoOper *); /* <=== AND HERE */

    if((tn=malloc(tam))==NULL)
        yyerror("Memory fault (cod. 4)");

    tn->oper = o;
    tn->nops = n;
    va_start(ap, n);
    for(i=0; i<n; i++)
        tn->ptn[i] = va_arg(ap, nodoOper*);
    va_end(ap);
    return tn;
}

(I've simplified the whole struct and code here, because it uses two more structs that is not important to the question, so maybe this example has bugs )

Now, the struct definition is in a header file (.h), and the code create a syntax tree for a compiler. How can I change the array to use variable length?

Thanks! Beco.

Edited: rolling back the last editon to Flexible Array Member.

2nd edition. Suppose I add inside the function this piece of code:

struct nOp
{
    int oper;             /* some operator */
    int nops;             /* number of args */
    struct nOp *ptn[n];   /* Variable Length Array (VLA) */
};
struct nOp tnop;
struct nOp *tn2;

tn2 = &tnop;
return tn2;

First problem I see, I'm returning a pointer to a local variable. But beside that, is the way fruitful? Thanks


回答1:


Actually, it's not variable-length arrays that you want to use here, but the struct hack, aka "incomplete types", aka the "flexible array member":

typedef struct nO
{
    int oper;
    int nops;
    struct nO *ptn[];  // <== look ma, no index!
} nodoOper;

// skip a bit
// no more (n-1) --------\
tam = sizeof(nodoOper) + n * sizeof(nodoOper *);

Only the last member of a struct may be "flexible".

Variable-length arrays are a different feature:

void foo(int size)
{
    float a[size];               // run-time stack allocation
    printf("%lu\n", sizeof(a));  // and run-time sizeof (yuck)
}

(Oh, and these things are called arrays, not matrices.)




回答2:


The C name for that construction is "flexible array member" (it might help your searches), or "struct hack" before C99.

Look at 6.7.2.1 in the Standard; there is example usage in the text.


You may also be interested in "Variable Length Arrays". See 6.7.5.2 in The Standard.



来源:https://stackoverflow.com/questions/5478706/flexible-array-member-c99-inside-a-structure

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!