问题
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