Jump to page: 1 2
Thread overview
@safe @nogc memory allocation
May 28, 2014
Nordlöw
May 28, 2014
monarch_dodra
May 28, 2014
safety0ff
May 28, 2014
monarch_dodra
May 28, 2014
Nordlöw
May 28, 2014
Dicebot
May 28, 2014
bearophile
May 28, 2014
Dicebot
May 28, 2014
Nordlöw
May 28, 2014
Dicebot
May 29, 2014
safety0ff
May 28, 2014
I would like my radix sort function radixSortImpl() at

https://github.com/nordlow/justd/blob/master/intsort.d

to not use the GC. However, when I tag with @nogc I get the error:

intsort.d(195,47): Error: @nogc function 'isort.radixSortImpl!(byte[], "a", false).radixSortImpl' cannot call non-@nogc function 'std.array.uninitializedArray!(byte[], immutable(ulong)).uninitializedArray'

Is there an alternative to

std.array: uninitializedArray
Elem[] y = uninitializedArray!(Elem[])(n);

that neither use the GC and nor preinitialize the data?

Could the recent DMD pull optimization to scope here

https://github.com/D-Programming-Language/dmd/commit/abc7033bf9cf7f7224a47e45096efc48a21b5ab8

be used?

/Per
May 28, 2014
On Wednesday, 28 May 2014 at 19:43:53 UTC, Nordlöw wrote:
> I would like my radix sort function radixSortImpl() at
>
> https://github.com/nordlow/justd/blob/master/intsort.d
>
> to not use the GC. However, when I tag with @nogc I get the error:
>
> intsort.d(195,47): Error: @nogc function 'isort.radixSortImpl!(byte[], "a", false).radixSortImpl' cannot call non-@nogc function 'std.array.uninitializedArray!(byte[], immutable(ulong)).uninitializedArray'
>
> Is there an alternative to
>
> std.array: uninitializedArray
> Elem[] y = uninitializedArray!(Elem[])(n);
>
> that neither use the GC and nor preinitialize the data?

malloc? There's no wrapper around it though, like there is for uninitializedArray.

Keep in mind though that currently, you have to choose either of "pure" (GC) or "nogc" (malloc) if you need dynamic allocation :/

> Could the recent DMD pull optimization to scope here
>
> https://github.com/D-Programming-Language/dmd/commit/abc7033bf9cf7f7224a47e45096efc48a21b5ab8
>
> be used?
>
> /Per

I don't think scope can be used to create a dynamic array on the stack. I think it requires the object's type be statically known. I could be wrong though.

If you know "n" has a max size, you could you create a fixed size array, or attempt a "alloca" array?
May 28, 2014
I think malloc isn't @safe and alloca doesn't work if your function can throw.
May 28, 2014
On Wednesday, 28 May 2014 at 20:00:17 UTC, safety0ff wrote:
> I think malloc isn't @safe and alloca doesn't work if your function can throw.

Yeah, uninitializedArray is also *only* trusted if the type in question has no indirections.

I've heard of several bugs with alloca, but I don't know the exact list.
May 28, 2014
> malloc? There's no wrapper around it though, like there is for uninitializedArray.

Is the fact that

malloc() can't be pure when new is

a limitiation in the type system?

Do we need a yet another code tag for this?

/Per
May 28, 2014
On Wednesday, 28 May 2014 at 20:51:08 UTC, Nordlöw wrote:
>> malloc? There's no wrapper around it though, like there is for uninitializedArray.
>
> Is the fact that
>
> malloc() can't be pure when new is
>
> a limitiation in the type system?
>
> Do we need a yet another code tag for this?
>
> /Per

It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.
May 28, 2014
Dicebot:

> It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.

One wrapper should have a template argument to specify the type of the items, to avoid the need of a cast. And instead of throwing an error it could also return a Nullable (the sizeof of such Nullable is the same as a pointer).

Nullable!(Titem*, null) talloc(Titem)(in size_t nItems);

Bye,
bearophile
May 28, 2014
On Wednesday, 28 May 2014 at 21:09:26 UTC, bearophile wrote:
> Dicebot:
>
>> It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.
>
> One wrapper should have a template argument to specify the type of the items, to avoid the need of a cast. And instead of throwing an error it could also return a Nullable (the sizeof of such Nullable is the same as a pointer).
>
> Nullable!(Titem*, null) talloc(Titem)(in size_t nItems);
>
> Bye,
> bearophile

I don't think wrapper with Nullable can be pure as it will possibly return two different object values (and not just different pointers) when called with same argument list. Throwing an Error is crucial here.
May 28, 2014
> It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.

Does this mean that I should write and use such a wrapper for malloc?

/Per
May 28, 2014
On Wednesday, 28 May 2014 at 21:31:41 UTC, Nordlöw wrote:
>> It is also because `malloc` can return null when out of memory and `new` will throw an Error. Wrapper around `malloc` that throws `OutOfMemoryError` on null can be considered of same purity class as `new`.
>
> Does this mean that I should write and use such a wrapper for malloc?
>
> /Per

I don't know. I believe within current language semantics even considering `new` pure is broken, there was a very recent thread discussing it in digitalmars.D group.

If you can be sure that your code won't break basic sanity requirements (never comparing allocated immutable pointer identity, only pointed values) it should work fine. But I have never done it in my code and not aware of possible pitfalls.
« First   ‹ Prev
1 2