[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Tinycc-devel] Buiding binutils 2.17 (needs dynamic arrays).

From: Rob Landley
Subject: Re: [Tinycc-devel] Buiding binutils 2.17 (needs dynamic arrays).
Date: Wed, 3 Oct 2007 01:59:47 -0500
User-agent: KMail/1.9.6

On Wednesday 03 October 2007 12:07:21 am Antti-Juhani Kaijanaho wrote:
> On Tue, Oct 02, 2007 at 12:19:18PM -0500, Rob Landley wrote:
> > Any opinions on how to tackle this one?
> No.  But I'll summarise (NOT quote) the C99 rules, in case it's helpful.
> Feel free to ask questions :)
> The C99 term is "variable length array" (VLA).

Is it?  I thought it was a gcc extension.  Ok...

Searching through my copy of the c99 draft for "variable length array"...

Ah, fun, I forgot about initializing char [] = "fruitbasket"; so [] is valid 
and _that_ already uses n=-1, so I need to set n=-2 for variable length array 
to indicate "pop something off the stack to get this value".  Right...

Why is it using recursion here?  It does mean the symbols are pushed last to 
first, but why is that important?  (The length value pushed onto the stack is 
done first to last, because it happens before the recursion.  That's unlikely 
to work.  Right now it hits an error() in that case, but that's just a 

Sigh... #7 applies sizeof() to a variable length array, and yup it's got to 
calculate this at runtime.  Suckage...

Argh!  And you can do "char thing[a][b];" too, and take sizeof(thing)...

> int a[*] (the asterisk is literal) is allowed in parameter declarations
> in function prototypes but not in function definitions.  The array is a
> VLA and its length is unknown.

What does "the asterisk is literal" here mean?  I'm familiar with "int blah[] 
= {1,2,3};" but if I stick a * between the [] I get:

temp.c:5: warning: GCC does not yet properly implement ‘[*]’ array declarators

And if gcc 4.x doesn't implement it, no Linux program anywhere uses it.

> The expression inside [ ] in a variable (or typedef) declaration needs
> not be a constant expression.  If it is not constant, then the array is
> a VLA.   If the VLA declaration defines a function parameter in a
> prototype, the effect is the same as if the expression had been replaced by
> asterisk.

The effect being that even gcc doesn't support it, so I shouldn't worry about 
it?  (I don't really care what the standard says, I care about what actual 
programs do.)

> When testing array types for compatibility, array sizes are compared
> only if both are present and constant.
> If a typedef includes VLA types (for example, typedef int foo[n], where
> n is not a constant), then the non-constant size expressions are
> evaluated when the typedef declaration is encountered during execution.
> Thus the size of a VLA typedef is fixed while the typedef name is in
> scope.  The standard gives an example in 6.7.7:8:

Where the heck would N come from here, variable length arrays can't have 
static storage duration, they can only be automatic (I.E. local) variables...

>   EXAMPLE 5 If a typedef name denotes a variable length array type, the
>   length of the array is fixed at the time the typedef name is defined,
>   not each time it is used:
>                void copyt(int n)
>                {
>                       typedef int B[n]; // B is n ints, n evaluated now
>                       n += 1;
>                     B a;              // a is n ints, n without += 1
>                     int b[n];         // a and b are different sizes
>                       for (int i = 1; i < n; i++)
>                               a[i-1] = b[i];
>                }

That's sick and evil and pointless.  What the heck is the point of a typedef 
with local scope???  Use "int B" already.  I might start caring about that 
case if I run into real software that does that, but until then the standards 
body seems to be hallucinating another edge case.  (Support for this might 
fall out naturally from the existing tcc typedef handling, but if it doesn't 
throwing an error upon encountering that construct is fine by me.  I'll 
accept a patch but not come up with one on my own...)

> A VLA cannot be initialized explicitly.

Currently only [] arrays can be.  Even if I say 'char blah[42]="abc";' gcc 
tells me [*] is unimplemented.

> When a local VLA variable is declared, the non-constant size expressions
> are evaluated at that time.

And thrown on the stack using a hidden symbol?  Yeah, I can see that.  (Kind 
of what I was thinking of doing, I just have to keep multi-level arrays in 
mind here.  Wheee...)

> VLAs are not allowed as struct and union members.


> Only local variables may be VLA variables.

Yup, I'd noticed that one.

> It is not allowed to jump over a VLA declaration by goto, switch or
> setjmp-longjmp.  The compiler must diagnose violations of this by goto
> and switch.

You know, with tcc being a one-pass compiler, there's a certain amount of suck 
in that statement.  I'll have to think about it...

> Size expressions of VLA parameters are evaluated when the function is
> called.

How would that work?  (Do you have an example here?)

I'm still somewhat confused by VLA parameters.  The expression would almost 
have to consist of globals, unless you mean:

int blah(char a, char b[a]) {

except I thought the order of evaluation of function parameters wasn't 
guaranteed, and does that mean char b[a] gets declared before char[a] does?

Seems dodgy, somehow...

> The size of a VLA variable does not change during the variable's
> lifetime.

That part I knew.  It boils down to a funky call to alloca()...

"One of my most productive days was throwing away 1000 lines of code."
  - Ken Thompson.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]