Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread bearophile via Digitalmars-d-learn

Bienlein:


Is there a way to get around this?


Perhaps there are ways, but note that @nogc is meant mostly for 
stack-allocation.
In general when in D you have to write lot of hairy code to do 
something, it means that in most cases you shouldn't do that 
something.




When calling delete t the protection violation


Don't use "delete", it's deprecated (despite it's not yet 
deprecated because D designers love to keep some important things 
in such Limbo for several years).


Bye,
bearophile


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread Jacob Carlborg via Digitalmars-d-learn

On 2014-08-24 10:03, Bienlein wrote:


I have omitted the code for the TestClass class to save space. Problem
is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call
non-@nogc function 'core.exception.onOutOfMemoryError'
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' cannot call
non-@nogc function 'std.conv.emplace!(TestClass, ).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' cannot call
non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this?


@nogc is a very new attribute. The runtime and standard library have not 
been properly annotated with this attribute yet.


As a workaround you could try copy implementation of these functions to 
you're own code and annotate them as appropriate.


--
/Jacob Carlborg


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread Bienlein via Digitalmars-d-learn

On Sunday, 24 August 2014 at 08:48:03 UTC, bearophile wrote:

Perhaps there are ways, but note that @nogc is meant mostly for 
stack-allocation.


Ah, I missed that. Thanks for telling me. I changed nogcDel now 
to null out the deallocated object:


void nogcDel(T)(ref T obj)
{
import core.stdc.stdlib : free;

// calls obj's destructor
destroy(obj);

// free memory occupied by object
free(cast(void*)obj);

obj = null;
}

And now I also get the dearly missed protection violation ;-).


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread eles via Digitalmars-d-learn

On Sunday, 24 August 2014 at 08:48:03 UTC, bearophile wrote:

Bienlein:



things in such Limbo for several years).


decades


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread bearophile via Digitalmars-d-learn

Bienlein:


@nogc is meant mostly for stack-allocation.


Ah, I missed that. Thanks for telling me.


@nogc is also for allocation from the C heap, despite this is 
less common :-)


Bye,
bearophile


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread Kagamin via Digitalmars-d-learn

On Sunday, 24 August 2014 at 09:29:53 UTC, Jacob Carlborg wrote:

On 2014-08-24 10:03, Bienlein wrote:

I have omitted the code for the TestClass class to save space. 
Problem

is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'core.exception.onOutOfMemoryError'
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'std.conv.emplace!(TestClass, ).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' 
cannot call

non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this?


@nogc is a very new attribute. The runtime and standard library 
have not been properly annotated with this attribute yet.


As a workaround you could try copy implementation of these 
functions to you're own code and annotate them as appropriate.


Shouldn't emplace and destroy infer their attributes instead of 
strictly annotating them as nogc.


Re: How to get nogc to work with manual memory allocation

2014-08-24 Thread Jacob Carlborg via Digitalmars-d-learn

On 2014-08-24 14:18, Kagamin wrote:


Shouldn't emplace and destroy infer their attributes instead of strictly
annotating them as nogc.


If they are templates, I guess they should. I don't know how good the 
compiler is at inferring attributes. I also haven't looked at the source 
code for these functions so I don't know if there's anything stopping 
them from begin @nogc.


--
/Jacob Carlborg


Re: How to get nogc to work with manual memory allocation

2014-09-04 Thread Kagamin via Digitalmars-d-learn

On Sunday, 24 August 2014 at 13:27:01 UTC, Jacob Carlborg wrote:

On 2014-08-24 14:18, Kagamin wrote:

Shouldn't emplace and destroy infer their attributes instead 
of strictly

annotating them as nogc.


If they are templates, I guess they should. I don't know how 
good the compiler is at inferring attributes. I also haven't 
looked at the source code for these functions so I don't know 
if there's anything stopping them from begin @nogc.


emplace calls constructor, and constructor can't be realistically 
required to be nogc. It depends on the constructor. Similar for 
destroy.


Re: How to get nogc to work with manual memory allocation

2014-09-04 Thread Kiith-Sa via Digitalmars-d-learn

On Sunday, 24 August 2014 at 08:03:11 UTC, Bienlein wrote:

Hello,

I was having a look at the new nogc annotation and therefore 
wrote some code that creates an instance on the heap bypassing 
the GC (code adapted from http://dpaste.dzfl.pl/2377217c7870). 
Problem is that calls to call the class' constructor, 
destructor and others can't be called anymore once nogc is 
used. So the question is how to get manual allocation and 
deallocation done with using nogc. Here is the experimental 
code:


@nogc
T nogcNew(T, Args...) (Args args)
{
import std.conv : emplace;
import core.stdc.stdlib : malloc;

// get class size of class object in bytes
auto size = __traits(classInstanceSize, T);

// allocate memory for the object
auto memory = malloc(size)[0..size];
if(!memory)
{
import core.exception : onOutOfMemoryError;
onOutOfMemoryError();
}

// call T's constructor and emplace instance on
// newly allocated memory
return emplace!(T, Args)(memory, args);
}

@nogc
void nogcDel(T)(T obj)
{
import core.stdc.stdlib : free;

// calls obj's destructor
destroy(obj);

// free memory occupied by object
free(cast(void*)obj);
}

@nogc
void main()
{
TestClass test = nogcNew!TestClass();
test.x = 123;
nogcDel(test);
test.x = 456;   // no protection violation ?!

// remove @nogc to run this
TestClass t = new TestClass();
t.x = 789;
delete t;
t.x = 678;  // protection violation as expected
}

I have omitted the code for the TestClass class to save space. 
Problem is that the compiler outputs this:


Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call non-@nogc function 
'core.exception.onOutOfMemoryError'	
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call non-@nogc function 'std.conv.emplace!(TestClass, 
).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' cannot 
call non-@nogc function 'object.destroy!(TestClass).destroy'


Is there a way to get around this? Then the test.x = 456; did 
not cause a protection violation although the instance was 
deallocated before calling nogcDel. Something with the 
deallocation in nogcDel seems not to work. Some hint 
appreciated on this. When calling delete t the protection 
violation happens on the next line as expected.


Thanks a lot, Bienlein



@nogc is *no GC*, it has nothing to do with where you allocate 
from, no matter how some would choose to interpret it (I use it 
to mean 'no heap' pretty often in my own projects, though, can be 
useful).


You can mark it @nogc by wrapping the non-@nogc stuff in a 
function and casting it, but you *absolutely* must be sure GC is 
not used in any called functions.


You could possibly do that by requiring T's constructor to be 
@nogc, not sure if the other functions can use GC or not.



Also, your function seems to be written only for classes,
if this is intended, you should have an

if(is(T == class))

template constraint there.


Re: How to get nogc to work with manual memory allocation

2014-09-04 Thread Jacob Carlborg via Digitalmars-d-learn

On 04/09/14 22:30, Kagamin wrote:


emplace calls constructor, and constructor can't be realistically
required to be nogc. It depends on the constructor. Similar for destroy.


But if the constructor is @nogc or if there's a default constructor.

--
/Jacob Carlborg


Re: How to get nogc to work with manual memory allocation

2014-09-04 Thread monarch_dodra via Digitalmars-d-learn

On Sunday, 24 August 2014 at 09:29:53 UTC, Jacob Carlborg wrote:

On 2014-08-24 10:03, Bienlein wrote:

I have omitted the code for the TestClass class to save space. 
Problem

is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'core.exception.onOutOfMemoryError'
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'std.conv.emplace!(TestClass, ).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' 
cannot call

non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this?


@nogc is a very new attribute. The runtime and standard library 
have not been properly annotated with this attribute yet.


As a workaround you could try copy implementation of these 
functions to you're own code and annotate them as appropriate.


The real issue here is actually the *language*. Exceptions and 
Errors are GC allocated, so if you try to "check" your no-GC 
allocation, you'll use the GC...


A possible workaround is to preemptively static allocate the 
Error. However, this can cause issues if you chain Errors, or 
re-enter your function while throwing.


Re: How to get nogc to work with manual memory allocation

2014-09-05 Thread via Digitalmars-d-learn

On Friday, 5 September 2014 at 06:43:56 UTC, monarch_dodra wrote:

On Sunday, 24 August 2014 at 09:29:53 UTC, Jacob Carlborg wrote:

On 2014-08-24 10:03, Bienlein wrote:

I have omitted the code for the TestClass class to save 
space. Problem

is that the compiler outputs this:

Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'core.exception.onOutOfMemoryError'
Error: @nogc function 'main.nogcNew!(TestClass, ).nogcNew' 
cannot call

non-@nogc function 'std.conv.emplace!(TestClass, ).emplace'
Error: @nogc function 'main.nogcDel!(TestClass).nogcDel' 
cannot call

non-@nogc function 'object.destroy!(TestClass).destroy'

Is there a way to get around this?


@nogc is a very new attribute. The runtime and standard 
library have not been properly annotated with this attribute 
yet.


As a workaround you could try copy implementation of these 
functions to you're own code and annotate them as appropriate.


The real issue here is actually the *language*. Exceptions and 
Errors are GC allocated, so if you try to "check" your no-GC 
allocation, you'll use the GC...


A possible workaround is to preemptively static allocate the 
Error. However, this can cause issues if you chain Errors, or 
re-enter your function while throwing.


It was also discussed to exempt `new Error` (and assert) from the 
@nogc restriction.