Thread overview | |||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
April 21, 2018 dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uknown | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uknown | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Giles Bathgate | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Giles Bathgate | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mike Franklin | 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 Re: dynamically allocating on the stack | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | 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 |
Copyright © 1999-2021 by the D Language Foundation