Stack based object implementation in D

I am learning D, and I am confused by the error I receive.

Consider the following:

module helloworld; import std.stdio; import std.perf; ptrdiff_t main( string[] args ) { auto t = new PerformanceCounter; //From managed heap //PerformanceCounter t; //On the stack t.start(); writeln( "Hello, ", size_t.sizeof * 8, "-bit world!" ); t.stop(); writeln( "Elapsed time: ", t.microseconds, " \xb5s." ); return 0; } //main() 

Gets a perfectly respectable:

 Hello, 32-bit world! Elapsed time: 218 ยตs. 

Now consider what happens when I try to initialize a PerformanceCounter on the stack instead of using a managed heap:

  //auto t = new PerformanceCounter; //From managed heap PerformanceCounter t; //On the stack 

Productivity:

 --- killed by signal 10 

I'm at a dead end. Any thoughts on why this breaks down? (DMD 2.049 on Mac OS X 10.6.4). Thanks in advance for helping n00b.

+6
stack allocation d raii phobos
source share
3 answers

It seems you are mixing C ++ classes with D classes.

D classes are always passed by reference (unlike, say, C ++ classes), and PerformanceCounter t does not allocate a class on the stack, but simply a pointer to it.

This means that t set to null , because, well, null is the default initializer for pointers - hence, an error.

EDIT: You can think of the D Foo class as C ++ Foo* .

If you want this to be allocated on the heap, you can try using structures instead of them - they can also have methods, like classes. However, they have no inheritance.

+5
source share

The most obvious answer is to use struct . If you are using a library that has no control over something, and heap allocation is a performance issue, you can use the std.typecons.scoped functionality to improperly allocate an instance of the class on the stack. The instance is still passed by reference, and if its lifetime exceeds the lifetime of the current stack frame, this will lead to undefined behavior. The scope keyword according to an anonymous answer will work, but it is planned to be deprecated in D2.

+3
source share

Thanks Tim.

Thanks to your answer, I was able to find the following at http://www.digitalmars.com/d/2.0/memory.html :


Distributing instance classes on the stack

Class instances are usually allocated to a bunch of garbage. However, if they are: distributed as local characters in a function, allocated using new ones, use new without arguments (constructor arguments are allowed) to have a storage class for the region, then they are allocated on the stack. This is more efficient than performing allocation / free looping of an instance. But be careful that any reference to an object does not leave a function return.

 class C { ... } scope c = new C(); // c is allocated on the stack scope c2 = new C(5); // allocated on stack scope c3 = new(5) C(); // allocated by a custom allocator 

If the class has a destructor, then this destructor is guaranteed to start when the class object goes out of scope, even if the scope leaves the exception.


Now my code is reading

 scope t = new PerformanceCounter(); //On the stack 

This (presumably) allocates on the stack and works fine. :)

Thanks again!

+1
source share

All Articles