tomhrr / dale

Lisp-flavoured C
BSD 3-Clause "New" or "Revised" License
1.02k stars 48 forks source link

dynamically sized, stack-allocated arrays cause segfaults at compile time #176

Closed porky11 closed 6 years ago

porky11 commented 7 years ago

This works in c:

#include <stdio.h>

void main() {
  int x = 1;
  float y[x];
  printf("no error?");
}

This should do the same in dale:

(import stdlib)

(def main (fn extern-c void (void)
  (let ((x \ 1)
        (y (array-of x float)))
    (printf "no error?\n"))))

This causes segfault at compile time. The c version also works, if x isn't constant. The problem in dale may also be, that arrays of different sizes are different types unlike in c. There are some solutions:

BitPuffin commented 7 years ago

Actually I believe your example C code isn't standard compliant. But some compilers support usage like that anyway.

As for Dale, I think I oppose pretty much all your suggestions. I think generally your last option listed with how C acts is generally considered a weakness of C[1]. If I'm not mistaken (array-of n T) is a static type. So (array-of 2 int) and (array-of 3 int) are two separate types, and no runtime data is allocated for the length. If I'm right, then this is good, much like std::array in C++, which fixes the issue with native C-style arrays.

For a dynamically allocated array I think that should be its own type. Call it sequence or something like that. Which will allocate on the stack (because otherwise you may as well use vector), and also allocate a number for holding the element count. You can probably implement this as a library since there are OS functions for arbitrary stack allocation (see alloca). And implement the copy semantics etc. Free it when it goes out of scope in the destructor [edit: actually is that even necessary/possible?].

Also, if you implement such a type, is there any reason to not allow it to grow dynamically? It can basically be a stack-vector Like why not.

[1] http://www.drdobbs.com/architecture-and-design/cs-biggest-mistake/228701625

porky11 commented 7 years ago

I don't think, when something is allocated on stack, it's possible to dynamically resize it.

BitPuffin commented 7 years ago

Yeah I guess not, it would work in theory if it was the element at the top of the stack. But that's probably usually not the case. So yeah good correction :P to be fair I wrote that at like 2am x)

tomhrr commented 6 years ago

Thanks, there was a problem with how the size expression was being evaluated, and that's now been fixed. I think the suggested alloca approach is the best one here, if VLAs are needed, since adding VLAs as a language-level feature is fairly complex (for each of the original suggested solutions) while bringing little additional benefit.