Jump to page: 1 2 3
Thread overview
dynamically allocating on the stack
Apr 21, 2018
Mike Franklin
Apr 21, 2018
Uknown
Apr 21, 2018
Giles Bathgate
Apr 21, 2018
Giles Bathgate
Apr 21, 2018
Giles Bathgate
Apr 21, 2018
Timon Gehr
Apr 21, 2018
Giles Bathgate
Apr 21, 2018
Mike Franklin
Apr 22, 2018
Nicholas Wilson
Apr 22, 2018
Mike Franklin
Apr 22, 2018
Cym13
Apr 22, 2018
Giles Bathgate
Apr 22, 2018
Giles Bathgate
Apr 22, 2018
Uknown
Apr 22, 2018
Adam D. Ruppe
Apr 22, 2018
Jonathan M Davis
Apr 21, 2018
Mike Franklin
Apr 21, 2018
Dmitry Olshansky
Apr 21, 2018
Cym13
Apr 21, 2018
H. S. Teoh
Apr 21, 2018
Cym13
Apr 21, 2018
Dmitry Olshansky
Apr 21, 2018
Cym13
Apr 21, 2018
Dmitry Olshansky
April 21, 2018
Does D have some way to dynamically allocate on the stack?  I'm looking for something roughly equivalent to the following C code.

int doSomething(size_t len)
{
    char stackBuffer[len + 1];
    doSomethingElse(stackBuffer);
}

Thanks,
Mike
April 21, 2018
On Saturday, 21 April 2018 at 07:37:50 UTC, Mike Franklin wrote:
> Does D have some way to dynamically allocate on the stack?  I'm looking for something roughly equivalent to the following C code.
>
> int doSomething(size_t len)
> {
>     char stackBuffer[len + 1];
>     doSomethingElse(stackBuffer);
> }
>
> Thanks,
> Mike

The language itself doesn't have something, but you could use `alloca`:

---
void doSomething(size_t len)
{
    import core.stdc.stdlib, core.stdc.stdio;

    auto stackBuffer = (cast(char*) alloca(char.sizeof * len + 1))[0 .. len + 1];
    stackBuffer[0] = 'H';
    stackBuffer[1] = '\0';
    printf("%.*s", stackBuffer.ptr);
}

void main()
{
    doSomething(2);
}
---
April 21, 2018
On Saturday, 21 April 2018 at 07:57:41 UTC, Uknown wrote:
> The language itself doesn't have something.

It would be cool if you could just do

--------
int doSomething(size_t len)
{
    char stackBuffer = push char[len + 1];
    doSomethingElse(stackBuffer);
}
--------

i.e some kind of `push` keyword instead of `new` perhaps its too much of an edge case.
April 21, 2018
On Saturday, 21 April 2018 at 07:57:41 UTC, Uknown wrote:
> The language itself doesn't have something, but you could use `alloca`

I don't know if this little template function makes life easier:

------
pragma(inline, true)
ref T push(T)(size_t len)
{
    import core.stdc.stdlib, core.stdc.stdio;

    return *cast(T*)alloca(T.sizeof * len);
}


void doSomething(size_t len)
{
    auto stackBuffer = push!char(len+1);
    stackBuffer[0] = 'H';
    stackBuffer[1] = '\0';
    printf("%.*s", stackBuffer.ptr);
}

void main()
{
    doSomething(2);
}
------


April 21, 2018
On Saturday, 21 April 2018 at 10:08:43 UTC, Giles Bathgate wrote:
> I don't know if this little template function makes life easier:

Sorry, that doesn't work at all.
April 21, 2018
On Saturday, 21 April 2018 at 07:37:50 UTC, Mike Franklin wrote:
> Does D have some way to dynamically allocate on the stack?  I'm looking for something roughly equivalent to the following C code.
>
> int doSomething(size_t len)
> {
>     char stackBuffer[len + 1];
>     doSomethingElse(stackBuffer);
> }

https://issues.dlang.org/show_bug.cgi?id=18788


April 21, 2018
On 21.04.2018 12:08, Giles Bathgate wrote:
> On Saturday, 21 April 2018 at 07:57:41 UTC, Uknown wrote:
>> The language itself doesn't have something, but you could use `alloca`
> 
> I don't know if this little template function makes life easier:
> 
> ------
> pragma(inline, true)
> ref T push(T)(size_t len)
> {
>      import core.stdc.stdlib, core.stdc.stdio;
> 
>      return *cast(T*)alloca(T.sizeof * len);
> }
> 
> 
> void doSomething(size_t len)
> {
>      auto stackBuffer = push!char(len+1);
>      stackBuffer[0] = 'H';
>      stackBuffer[1] = '\0';
>      printf("%.*s", stackBuffer.ptr);
> }
> 
> void main()
> {
>      doSomething(2);
> }
> ------
> 
> 

That does not work (you are returning a dangling reference into the stack of the function that is returning). You could do this:

import core.stdc.stdlib, core.stdc.stdio;
auto push(T,alias len)(T[] mem=(cast(T*)alloca(T.sizeof*len))[0..len]){
    return mem; // (uninitialized!)
}
void doSomething(size_t len){
    char[] stackBuffer=push!(char,len);
    stackBuffer[0] = 'H';
    stackBuffer[1] = '\0';
    printf("%s", stackBuffer.ptr);
}

void main(){
    doSomething(2);
}


April 21, 2018
On Saturday, 21 April 2018 at 10:47:47 UTC, Timon Gehr wrote:
> That does not work (you are returning a dangling reference into the stack of the function that is returning).

Yeah I had hoped that the pragma(inline, true) would solve that, but it dosesn't :(


April 21, 2018
On Saturday, 21 April 2018 at 07:37:50 UTC, Mike Franklin wrote:
> Does D have some way to dynamically allocate on the stack?  I'm looking for something roughly equivalent to the following C code.
>
> int doSomething(size_t len)
> {
>     char stackBuffer[len + 1];
>     doSomethingElse(stackBuffer);
> }
>

Unbounded allocation on stack is kind of anti-pattern and a potential DoS vector.

A separate region allocator is exactly as fast and can easily survive across boundaries of function calls.

Also you probably want something like char[X] = void;
 for efficiency if allocating on stack.

> Thanks,
> Mike


April 21, 2018
On Saturday, 21 April 2018 at 12:08:09 UTC, Dmitry Olshansky wrote:
> On Saturday, 21 April 2018 at 07:37:50 UTC, Mike Franklin wrote:
>> Does D have some way to dynamically allocate on the stack?  I'm looking for something roughly equivalent to the following C code.
>>
>> int doSomething(size_t len)
>> {
>>     char stackBuffer[len + 1];
>>     doSomethingElse(stackBuffer);
>> }
>>
>
> Unbounded allocation on stack is kind of anti-pattern and a potential DoS vector.

I'm having trouble seeing how unbounded heap allocations aren't equally a potential DoS vector.

> A separate region allocator is exactly as fast and can easily survive across boundaries of function calls.

I guess if OP wants it on the stack it's because it doesn't need to survive across boundaries of function calls so this buys nothing in this case.

> Also you probably want something like char[X] = void;
>  for efficiency if allocating on stack.
>
>> Thanks,
>> Mike


« First   ‹ Prev
1 2 3