C2 forum

General Category => Ideas => Topic started by: lerno on November 02, 2018, 06:42:01 PM

Title: Relax variable initialization rules
Post by: lerno on November 02, 2018, 06:42:01 PM
According to the docs, this is not allowed:

Code: [Select]
i32 foo = 1;

i32[8] array = {
    [foo] = 1,    // error: initializer element is not a compile-time constant
}

However, there is no real reason why we could not support this:

Code: [Select]
func void foo(arg i32)
{
   i32[arg + 1] array = {
     [arg] = 1;
   }
}

As this is could be syntactic sugar for the following code:

Code: [Select]
func void foo(i i32)
{
   i32[i + 1] array = {}
   array[i] = 1;
}

It makes array usage more flexible and uniform. (Even though few might use this functionality)
Title: Re: Relax variable initialization rules
Post by: lerno on November 03, 2018, 03:05:59 PM
Also for consideration: VLAs are not really safe unless there is bounds checking, which is why they are removed from the linux kernel. I see three options:


(2) Might be the most flexible solution I think, but obviously less predictable than the others.
Title: Re: Relax variable initialization rules
Post by: bas on November 08, 2018, 11:59:39 AM
Here's what Linus Torvalds has to say about VLAs: https://lkml.org/lkml/2018/9/3/1288.

Of course he's not talking about the C2 compiler ;)

I think the designated array initializer syntactic sugar doesn't really bring anything, except
complexity. Is the code it replaced that much worse?

The first example (global array init) is allowed, but only by making foo const.
Title: Re: Relax variable initialization rules
Post by: lerno on November 08, 2018, 03:13:06 PM
I don't necessarily think that my proposed code is *needed*, instead I think it simplifies the rules of the language, which makes sense to me. Any rule "you can do this in some cases but not others" *will* be a bit arbitrary. Since this should not alter complexity of the language (when the analyser finds the code, it should edit the AST to reduce it to the above code for both C and LLVM)

To illustrate the complexity issue. Imagine this as refactoring steps:

Code: [Select]
const i32 foo_one = 31;
func void foo()
{
   i32[foo_one + 1] array = {
     [foo_one] = 1;
   }
   ...
}

"We let's make it more generic!"

Code: [Select]
func void foo(i32 one)
{
   i32[one + 1] array = {
     [one] = 1;
   }
   ...
}

"Let's clean it up"

Code: [Select]
func void foo(i32 one)
{
   i32[one + 1] array;
   array[one] = 1;
   ...
}

So more of an enabler of small steps of rewriting. In this case it's trivial, but consider if it's embedded in a bigger context. So it's not that I think it's a good idea for the end code, but code of "least surprise".
Title: Re: Relax variable initialization rules
Post by: bas on November 12, 2018, 10:16:10 AM
The last example compiles fine already. But for global arrays, it's not allowed since that could induce 'race conditions' between constants
Title: Re: Relax variable initialization rules
Post by: lerno on November 13, 2018, 12:15:03 AM
Oh, then I think I misunderstood.