6

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?

sig_seg_v
  • 570
  • 4
  • 15
  • 7
    `inline` doesn't change the semantics of what happens in a function. – juanchopanza May 18 '16 at 21:06
  • Think of it like copy and pasting the code into the call site but wrapping it with `{}` to create a "function scope". – NathanOliver May 18 '16 at 21:11
  • 1
    Possible duplicate of [Why is the use of alloca() not considered good practice?](http://stackoverflow.com/questions/1018853/why-is-the-use-of-alloca-not-considered-good-practice) – πάντα ῥεῖ May 18 '16 at 21:13
  • perhaps have a look at the execute-around idiom, instead. – jaggedSpire May 18 '16 at 21:25
  • @πάντα, this isn't a question of whether it's good practice to use `alloca()` or not. I didn't write the api, I'm just using it. Whoever voted to close, I'd be happy to clarify this question if I knew where your confusion lay. – sig_seg_v May 18 '16 at 21:34
  • 1
    @NathanOliver that would be different... `alloca` space typically lasts until the end of the enclosing function, not the enclosing block. http://stackoverflow.com/questions/5407546/memory-allocated-with-alloca-gets-freed-at-end-of-function-or-at-end-of-scope – M.M May 18 '16 at 21:48
  • @sleeptightpupper I didn't write the code that uses `alloca`, and the linked "good practice" question and answers don't seem to mention inline functions, or much on the use of `alloca` at all. I'm not writing new code that contains `alloca`, and I'm not advocating that practice. Leaving memory management up to the compiler and avoiding "copy/paste" code duplications are both good practices where possible, if I am not mistaken. – sig_seg_v May 18 '16 at 22:02
  • @juanchopanza inline DO change the semantics of what happens in a function, especially with static variables. Static variables in inline functions are local to each place the function is called, so calling such function twice or calling it in a loop won't gave the same result. – Calvin-Ruiz Jun 09 '23 at 13:08

2 Answers2

5

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.

Thomas B Preusser
  • 1,159
  • 5
  • 10
  • Scope is irrelevant; it refers to the region of source code in which an identifier is visible at compile time. It's about lifetime / storage duration. – Keith Thompson Jan 16 '17 at 17:17
5

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.