tinycc-devel
[Top][All Lists]
Advanced

[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 17:17:23 -0500
User-agent: KMail/1.9.6

On Wednesday 03 October 2007 2:24:23 am Antti-Juhani Kaijanaho wrote:
> On Wed, Oct 03, 2007 at 01:59:47AM -0500, Rob Landley wrote:
> > > 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?
>
> That I'm not using it as a footnote marker or whatever :)  I mean that
> there actually is an asterisk between the brackets.
>
> 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
>
> [*] is only allowed in parameter declarations anyway, and even there
> only in function declarations (not definitions).
>
> For example:
>
> int foo(size_t, int [*]);
>
> ...
>
> int foo(size_t n, int arr[n])
> {
> ...
> }
>
> The former is a valid declaration of the latter function.  The asterisk
> just says that the array is a VLA, not a normal array (which you could
> declare as int []).
>
> > And if gcc 4.x doesn't implement it, no Linux program anywhere uses it.
>
> True :)
>
> > > A VLA cannot be initialized explicitly.
> >
> > Currently only [] arrays can be.  Even if I say 'char blah[42]="abc";'
> > gcc tells me [*] is unimplemented.
>
> Um, char blah[42] = "abc" should work in GCC too.
>
> Indeed, it does:

You're right, I had another line in there it was compaining about.

> > > 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...
>
> Correction: What is not allowed is jumping from outside a VLA's scope to
> inside its scope.  You may jump in the other direction :)

If you jump inside its scope you must initialize it (call alloca).  Sounds 
like you can't jump over the initialization.

> I think you just need to keep a list of all gotos with targets you haven't
> seen yet,

Yes, to implement "goto".

> and if that's nonempty at a VLA declaration, yell.

No, they could be jumping entirely past the block with the VLA in it.  When 
declaring a new label inside a VLA, mark it "hot" somehow, and any attempt to 
use that target from a goto that's either before the declaration or which 
occurs after the end of the block, error() out.  (Note that according to c99, 
the declaration doesn't have to be at the start of the block, and due to the 
non constant size calculation, this unfortunately matters...)

> (Similar for  
> switches.) Bah, that doesn't handle the following scenario:
>
>    int n = 42;
>    {
>      int a[n];
>      ...
>      foo:
>      ...
>    }
>    ...
>    goto foo;
>
> I guess you need to also keep a list of all labels in the scope of a VLA
> declaration (with an associated list of those declarations).

You only need to keep track of this from the label perspective, and then when 
using those labels to resolve a goto, determine whether or not it's ok.

Something similar is needed for dead code elimination of blocks anyway.  A 
label can switch one of those back _on_.  (Which isn't implemented yet but 
which is a todo item of mine and can still be done in a single pass if you 
conditinally output the block to a temporary buffer and then either dump the 
whole thing to cur_text_section or discard it when you reach the end.)

> > > 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]) {
> >   thingy();
> > }
>
> THat's what I mean, yes.
>
> > 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?
>
> No, declaration is left-to-right, which means that any parameters
> defined before a parameter are in scope when that parameter is being
> defined.  Still the function *arguments* (the epressions in the call
> site) are evaluated in an unspecified order.
>
> Consider the following code fragment:
>
> int foo(size_t n, int arr[n++])
> {
>       ...
> }

In the absence of code I care about actually doing this, I'm not even going to 
try to support that.  Just use int *arr and copy the darn thing with alloca() 
if you need to.  This is getting _way_ too fancy at the language level...

> ...
> foo(k-1, kraah+1)
>
>
> So what happens is, when the call is executed:
>
>   k-1 and kraah+1 are evaluated in an unspecified order
>
>   the result of k-1 is assigned to the paramerter n, and the result of
>   kraah+1 is assigned to the parameter arr
>
>   n++ (the size expression) is evaluated
>
>   the function body is executed
>
> as far as I can tell.

kraah+1 resolves to a pointer, that should be what gets passed on the stack, 
and if the function wants to copy if the function can copy it.

Darn silly to try to make the language do this.  This is C, not python...

Rob
-- 
"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]