3

Suppose I have the following function, which makes use of a variable-length array:

void func(int size)
{
    int var1;
    int arr[size];
    int var2;
    ...
}

How does the compiler determine the address of var2?

The only way that I can think of is by placing arr after var1 and var2.

But in that case, what if there were several variable-length arrays?

Placing all of them after the "normal" variables would only help resolving the address of the first one.

My implicit assumption here is that all the local variables (including VLAs) are allocated on the stack.

I realize that it is not defined by the C99 standard, so the question is in essence about compilation.

user207421
  • 305,947
  • 44
  • 307
  • 483
barak manos
  • 29,648
  • 10
  • 62
  • 114
  • 1
    Does it really matter? And it's not specified anywhere, a compiler may place it anywhere it wants to, and it may differ from compiler to compiler. Also, there is actually nothing in the specifications that talks about stacks, and there are systems *without* a stack that is targeted by C compilers. – Some programmer dude Jul 28 '14 at 06:44
  • @DavidHeffernan: Well... Isn't there a standard for compilers to follow and implement VLAs? – barak manos Jul 28 '14 at 06:44
  • @JoachimPileborg: Same comment as above. – barak manos Jul 28 '14 at 06:45
  • 1
    @barak any compiler can do it however it likes. The standard defines **what** the compiler does, not **how** it does it. – David Heffernan Jul 28 '14 at 06:46
  • `var2` doesn't need to be located at a fixed offset from anything. The compiler can write some extra code to compute locations instead of using fixed offsets. It's already doing that to compute where `arr` is, assuming VLAs are on the stack and the stack grows down. – user2357112 Jul 28 '14 at 06:48
  • @user2357112: Wow, that could yield some serious performance implications... – barak manos Jul 28 '14 at 06:50
  • @barak Compiler is free to do it however it pleases, so long as it works – David Heffernan Jul 28 '14 at 06:51
  • @DavidHeffernan: So you (personally) wouldn't use VLAs on a RT application then...? – barak manos Jul 28 '14 at 06:52
  • I'm just trying to get you to realise that implementation is compiler specific. – David Heffernan Jul 28 '14 at 07:00

2 Answers2

2

Step 1: For each variable size item, create a hidden variable containing a pointer to the array, and a hidden variable holding the size of the array. These may be optimisied away, assigned to registers etc. as any other variable.

Step 2: Allocate space for non-variable size items in the normal way.

Step 3: To process the declaration of the variable size item, evaluate the size and store it into the size variable. Calculate the space for the variable size item, taking into account alignment. Make space on the stack for the variable size item, then store a pointer to the location of the item into the hidden pointer variable.

Step 4: Use the hidden pointer variable to access array elements. Use the hidden size variable for the sizeof operator.

gnasher729
  • 51,477
  • 5
  • 75
  • 98
1

Here is one possible model. Think of arr as a (fixed-size) pointer to a stack-allocated array:

int var1;
int *arr = alloca(sizeof(int) * size);
int var2;

Note how the (relative) location of the three variables does not change with size. This model readily generalizes to multiple VLAs.

Note that this is only an example. Each compiler is free to implement VLAs however it pleases. If you want to know what your compiler does, look at the generated assembly code.

NPE
  • 486,780
  • 108
  • 951
  • 1,012
  • 1
    Well, so my assumption about VLAs being always allocated on the stack is wrong then? – barak manos Jul 28 '14 at 06:45
  • @barakmanos: That's not specified. In the model suggested in the answer, arr_data does go on the stack. – NPE Jul 28 '14 at 06:46
  • Oh, so you do place all VLAs **after** the "normal" variables then? – barak manos Jul 28 '14 at 06:47
  • @barakmanos: Yes, that's the idea (not the only possible idea, mind you). – NPE Jul 28 '14 at 06:49
  • Thanks!!! Can you please explain `alloca`? Is it on the heap? At the end of the stack? – barak manos Jul 28 '14 at 06:50
  • @barakmanos: `alloca` is on the stack, and it's a "special" function that the compiler knows about internally (i.e. it cannot be written in standard C). – user541686 Jul 28 '14 at 06:53
  • @barakmanos Yes, but even without considering this example. There's no such thing as "the stack" or "the heap" as far as the C standard is concerned -- that's just an implementation detail. – The Paramagnetic Croissant Jul 28 '14 at 07:07
  • @TheParamagneticCroissant: As I stated at the bottom of the answer: "I realize that it is not defined by the C99 standard, so the question is in essence about compilation". – barak manos Jul 28 '14 at 07:27
  • @barakmanos Another quote of yours: "Isn't there a standard for compilers to follow and implement VLAs?" – David Heffernan Jul 28 '14 at 08:59
  • @DavidHeffernan: Yep, in one of the comments above. Is there something obviously wrong with this question? – barak manos Jul 28 '14 at 09:05
  • I'm just countering your comment to @TheParamagneticCroissant which was reasonable to me given the question and your comments. – David Heffernan Jul 28 '14 at 09:10