1

Is it possible to wrap the C function alloca into "another"? (only macros of course)

Something like:

#define my_alloca(size)                                      \
                             ({                               \
                                   void *ret = alloca(size);  \
                                   my_function(ret);          \
                             ret;})

I'm not quite sure about this, does the extension 6.1 Statements and Declarations in Expressions create a new stack frame? (It kinda looks so because of the curly brackets)

EDIT:

It did some testing on it:

#define printStackFrameAddr(_fnc)   \
    printf("%-20s: %p \n", _fnc, __builtin_frame_address(0))


void _my_init(void *mem)
{

}

void *notSafeAlloca(size_t num)
{
    void *mem;
    
    printStackFrameAddr("notSafeAlloca");
    
    mem = alloca(num);
    
    _my_init(mem);
    
    return mem;
}

#define safeAlloca(_num)            \
    ({                              \
        void *ret = alloca(_num);   \
        _my_init(ret);              \
        printStackFrameAddr("safeAlloca");      \
    ret;})

int main(int argc, const char * argv[])
{
    printStackFrameAddr("main");
    
    
    {   /* <- creates no new stack frame ? */
        int *array = notSafeAlloca(sizeof(* array) * 4);
        
        printStackFrameAddr("main");
        
        printf("\t%-20s: %p\n", "array", array);
    }
    
    {   /* <- creates no new stack frame ? */
        int *array = safeAlloca(sizeof(* array) * 4);
        
        printStackFrameAddr("main");
        
        printf("\t%-20s: %p\n", "array", array);
    }
    
    return 0;
}

Output:

main                : 0x7fff5fbff8d0 
notSafeAlloca       : 0x7fff5fbff860 
main                : 0x7fff5fbff8d0 
        array               : 0x7fff5fbff820
safeAlloca          : 0x7fff5fbff8d0 
main                : 0x7fff5fbff8d0 
        array               : 0x7fff5fbff888

The alloca() function allocates size bytes of space in the stack frame of the caller

So, is this above approach safe?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Marco
  • 7,007
  • 2
  • 19
  • 49
  • Braces do not act like a stack frame [In C, do braces act as a stack frame?](http://stackoverflow.com/questions/2759371/in-c-do-braces-act-as-a-stack-frame) – Marco May 31 '14 at 00:58
  • Your tests in `main()` are inconclusive; the chances are that the 'array' was optimized out because it isn't used. You should at least print the address (`printf("%p\n", array);`) and see if that alters anything. – Jonathan Leffler May 31 '14 at 01:03
  • @JonathanLeffler Nope, still same stack frame address. – Marco May 31 '14 at 01:06
  • [http://stackoverflow.com/questions/2614561/whats-the-difference-between-allocan-and-char-xn](http://stackoverflow.com/questions/2614561/whats-the-difference-between-allocan-and-char-xn) – Marco May 31 '14 at 01:30
  • 1
    @d3l: It's not so simple. For the purpose of compound literals, automatic variables, etc. the end of the block does end the lifetime of such objects. `alloca` is rather special in that the objects it creates have lifetime associated with the calling function rather than a block. The question to be asking is not whether braces "create a stack frame" but rather "what is the lifetime of an object created by `alloca`?" – R.. GitHub STOP HELPING ICE May 31 '14 at 03:01

2 Answers2

3

Got a solution for my problem :)

void *_my_alloca(void *memory)
{
    // init memory & stuff

    return memory;
}

#define my_alloca(_size)   _my_alloca(alloca(_size))

int main(int argc, const char **argv)
{
    int *array = my_alloca(sizeof(* array) * 4);
}
Marco
  • 7,007
  • 2
  • 19
  • 49
0

I doubt you can, but more importantly, why would you want to? This is a serious bug!

You'd be allocating something on the stack to have it destroyed on the stack the very same instruction you return it! It would almost certainly be overwritten on the stack before you ever had a chance to use it.

abelenky
  • 63,815
  • 23
  • 109
  • 159
  • I know about this, my question is about if "6.1 Statements and Declrations in Expression" creates a new **stack frame**. If it is not, then it would be perfectly fine. – Marco May 31 '14 at 00:41