This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/AM3359: Local array unexpectedly allocated on heap rather than stack

Part Number: AM3359

Tool/software: TI C/C++ Compiler

The TI compiler (in this case, ARM compiler 17.6.0 STS) sometimes generates a call to "malloc" to allocate storage for a local array.  For example in the following code, notice the call to "vla_alloc":

You can see why this happens - the compiler isn't sure of the array size at compile time (even though the size variable is const) so it can't fix the function's stack frame size and instead does it at run-time.  However, in my application I don't have a heap, so this code fails.

For comparison, I tried similar code in Microsoft Visual Studio - this is "smart" enough to see that the size is const and thus allocates space in the stack frame.  In fact, the compiler will raise an error not generate code if the array size is not constant.

My questions are:

1. Are there any other cases where the TI compiler will generate a hidden call to malloc (or vla_alloc)?

2. Is it possible to disable this behaviour?

3. Can the compiler be updated to raise a warning or error if it is unable to put local variables on the stack? It feels like the TI compiler is trying to be helpful, but the behaviour is counter-intuitive as most users would expect local variables to live on the stack, and it fails entirely if the application has no heap (which is common in safety-critical systems).

  • You might be able to make it static. Or, of course you could make it a #define.
  • 1. Not off the top of my head. Of course library routines (e.g. printf and operator new) will call malloc "under the hood," but I don't think you'd consider that hidden. vla_alloc is used strictly for VLA locals in the manner you have observed above.

    2. No.

    3. That is an interesting enhancement request. I've submitted CODEGEN-4550 so that this request may be considered.

    In the mean time, you may be able to find a third-party static analysis tool to look for instances of VLA locals in your code base.
  • A few more comments ...

    Based on the source code you show in that screen shot, I cannot see anything about size on line 87, except that is not the u32_Size on line 80.  However, it is a good guess that it is also a global const variable.

    When I build code similar to this with version 18.1.1.LTS, it does not call __vla_alloc, but puts the variable length array on the stack.  So upgrading to version 18.1.1.LTS is a solution to consider.

    Thanks and regards,

    -George

  • Sorry, typo with "size" vs "u32_Size", I was just tweaking for a good screenshot.  You're right, it's also const.

    Thanks, I'll try updating the compiler.

  • Yeah, I did use a #define in the end. I'm trying to use fewer #defines as variables provide more opportunities for static analysers to find bugs.
  • Thanks for raising the enhancement request. I can't quite figure out if the TI approach is a compiler extension as my reading of Kernighan & Ritchie doesn't mention this - it states that dynamic memory allocation is strictly not part of the language (malloc is simply a library function). The Microsoft compiler simply doesn't allow this code as I mentioned above. If it is an extension, I'd expect some control over it. We actually compile against C99, maybe it's allowed in C99.

    Thanks for the suggestion of analysing our code - we do analyse our code for any library calls in order to meet our verification coverage requirements.
  • VLA are defintely not a standard C89 feature. They are a standard C99 feature. As an extension, the TI compiler allows C99-style VLA in C89 mode.
  • Thanks, that explains it all.  Using the heap seems a slightly risky solution though: heaps have non-deterministic behaviour and, in my case, there isn't one.  In contrast, the stack is always there, although it too could run out of space.  From a quick search, GCC uses the stack for VLAs.