Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a variable is allocated on the stack in an inline function using alloca, is its reference valid after the inline function returns?

Tags:

c++

g++

inline

I know that the compiler may, not shall unroll inline functions into the calling function to avoid the overhead associated with calling out-of-line functions. I also know, however, that inline functions are linked differently than out-of-line functions, so I can't expect them to act the same way, exactly.

While I am actually using C++, I'm developing a program using an api in which it is convenient to make use of C macros that look something like:

#define func_alloca(ptr) do { *ptr = alloca(size); memset(*ptr, 0, size); }

In the interest of not repeating code several times in different functions, it would be useful for me to be able to functionalize a series of these alloca calls. My question is, (in gcc specifically, since alloca is implementation-defined,) can I initialize variables on the stack using alloca, inside an inline function, and count on them to work outside? Here's an example of what I want to do:

inline void uses_alloca(type*& ptr){
    // do stuff
    func_alloca(ptr);
}

void calls_inline(){
    type *local_ptr;
    uses_alloca(local_ptr);
    // is local_ptr valid?
}

If it does work, will it always work? As in, not only when the compiler chooses to unroll the inline function into the calling function?

Edit:

My guess is that this probably will work in fact, since the alloca call is already valid outside the do{} local scope contained in the macro, and since, if I understand correctly, a function doesn't actually have a different level of scope in C++ than a do{} block. My question remains: is this the way alloca is supposed to work in gcc? Is this defined behavior?

like image 311
sig_seg_v Avatar asked May 18 '16 21:05

sig_seg_v


2 Answers

If you're using GCC, the intended behavior is that functions with alloca in them aren't inlined automatically. From tree-inline:

  /* Refuse to inline alloca call unless user explicitly forced so as
 this may change program's memory overhead drastically when the
 function using alloca is called in loop.  In GCC present in
 SPEC2000 inlining into schedule_block cause it to require 2GB of
 RAM instead of 256MB.  Don't do so for alloca calls emitted for
 VLA objects as those can't cause unbounded growth (they're always
 wrapped inside stack_save/stack_restore regions.  */

This of course doesn't take into account:

  • Bugs
  • The compiler inlining functions anyways because it's not perfect
  • Optimization switches, attributes
  • Bad luck

The GCC manual page on inline warns that inlined functions are ill-suited for alloca and Why is the use of alloca() not considered good practice? has a few horror stories as well.

Essentially if you're worried that inlining may affect the semantics of your code, don't rely on it.

like image 145
uh oh somebody needs a pupper Avatar answered Oct 01 '22 07:10

uh oh somebody needs a pupper


Declaring a function inline does not extend the scope of the contained variables to the scope, into which it is expanded. So, whatever alloca allocates is not at all guaranteed to be valid in the context that has called the function uses_alloca. If you use the macro func_alloca, you are fine because the macro text is literally expanded in place. However, the use of alloca itself is typically considered a bad practice.

like image 45
Thomas B Preusser Avatar answered Oct 01 '22 07:10

Thomas B Preusser