Re: DMD JSON output

2017-02-25 Thread rikki cattermole via Digitalmars-d-learn

On 26/02/2017 4:01 PM, ANtlord wrote:

Hello! I've encroutered intresting tool of DMD. It is dump of AST in
JSON format (dmd -X main.d). But I it contains only declaration of
methods, templates and structs. It doesn't contain statements like a
variables or nested functions inside function's body.

Is it possible to make dump with statements inside function's body? If
yes, how can I do this?

Thanks.


Not without modifying the source code.

I would recommend instead dscanner[0].
With its --ast export function (xml).

[0] https://github.com/Hackerpilot/Dscanner


DMD JSON output

2017-02-25 Thread ANtlord via Digitalmars-d-learn
Hello! I've encroutered intresting tool of DMD. It is dump of AST 
in JSON format (dmd -X main.d). But I it contains only 
declaration of methods, templates and structs. It doesn't contain 
statements like a variables or nested functions inside function's 
body.


Is it possible to make dump with statements inside function's 
body? If yes, how can I do this?


Thanks.


Re: Recommend: IDE and GUI library

2017-02-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 25 February 2017 at 21:26:32 UTC, XavierAP wrote:
It's not GUI projects that I would plan to work on, just 
something easy with basic functionality that I can use for my 
own utilities or test clients for libraries. And if there's 
anything with any kind of designer support (in which IDE)...


Well, if you use dqml you can use the official QML designer "Qt 
Quick Designer"[1].


You can also use GtkD[2], which supports loading[3] Glade[4] 
files.


[1] 
http://doc.qt.io/qtcreator/creator-using-qt-quick-designer.html

[2] https://github.com/gtkd-developers/GtkD
[3] 
https://github.com/gtkd-developers/GtkD/blob/master/demos/builder/builderTest.d

[4] https://glade.gnome.org/


Re: trick to make throwing method @nogc

2017-02-25 Thread Profile Anaysis via Digitalmars-d-learn

On Saturday, 25 February 2017 at 19:59:29 UTC, ikod wrote:

Hello,

I have a method for range:

struct Range {
immutable(ubyte[]) _buffer;
size_t _pos;

@property void popFront() pure @safe {
enforce(_pos < _buffer.length, "popFront from empty 
buffer");

_pos++;
}
}

I'd like to have @nogc here, but I can't because enforce() is 
non-@nogc.
I have a trick but not sure if it is valid, especially I don't 
know if optimization will preserve code, used for throwing:


import std.string;

struct Range {
immutable(ubyte[]) _buffer;
size_t  _pos;

this(immutable(ubyte[]) s) {
_buffer = s;
}
@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
auto _ = _buffer[$]; // throws RangeError
}
_pos++;
}
}

void main() {
auto r = Range("1".representation);
r.popFront();
r.popFront(); // throws
}

Is it ok to use it? Is there any better solution?

Thanks!


You can wrap a gc function in a nogc call using a function 
pointer that casts it to a nogc. You do this first by casting to 
void* then back to the same signature as the function + @nogc. 
This "tricks" the compiler in to calling the gc function from a 
nogc function. The problem is, of course, it is not safe if the 
gc is turned off as it will result in a memory leak. This may or 
may not be an issue with enforce depending on if it allocates 
before or after the check.






Re: Recommend: IDE and GUI library

2017-02-25 Thread XavierAP via Digitalmars-d-learn
On Saturday, 25 February 2017 at 20:03:17 UTC, Jacob Carlborg 
wrote:
There's no de factor library for creating GUIs in D. If you 
want a native look and feel, DWT is a good option. If you want 
the application to look the same on all platforms, there might 
be other better suited alternatives.


It's not GUI projects that I would plan to work on, just 
something easy with basic functionality that I can use for my own 
utilities or test clients for libraries. And if there's anything 
with any kind of designer support (in which IDE)...


Re: trick to make throwing method @nogc

2017-02-25 Thread ikod via Digitalmars-d-learn
On Saturday, 25 February 2017 at 20:49:51 UTC, Adam D. Ruppe 
wrote:
A wrapper that unifies these 4 steps like enforce is pretty 
easy to implement.


yeah easy to use exception in @nogc as long as the catch knows 
to free it too.


Alas, not my case. Exception can be catched not in my code.


Re: trick to make throwing method @nogc

2017-02-25 Thread Eugene Wissner via Digitalmars-d-learn
On Saturday, 25 February 2017 at 20:49:51 UTC, Adam D. Ruppe 
wrote:
On Saturday, 25 February 2017 at 20:40:26 UTC, Eugene Wissner 
wrote:

it builds and doesn't throw if I compile with:
dmd -release
though it causes a segfault, what is probably a dmd bug.


No, that's by design. assert(0) compiles to a segfault 
instruction with -release.


A wrapper that unifies these 4 steps like enforce is pretty 
easy to implement.


yeah easy to use exception in @nogc as long as the catch knows 
to free it too.


But anyway segfault is not very descriptive :)


Re: trick to make throwing method @nogc

2017-02-25 Thread Adam D. Ruppe via Digitalmars-d-learn
On Saturday, 25 February 2017 at 20:40:26 UTC, Eugene Wissner 
wrote:

it builds and doesn't throw if I compile with:
dmd -release
though it causes a segfault, what is probably a dmd bug.


No, that's by design. assert(0) compiles to a segfault 
instruction with -release.


A wrapper that unifies these 4 steps like enforce is pretty 
easy to implement.


yeah easy to use exception in @nogc as long as the catch knows to 
free it too.


Re: trick to make throwing method @nogc

2017-02-25 Thread Eugene Wissner via Digitalmars-d-learn

On Saturday, 25 February 2017 at 20:02:56 UTC, ikod wrote:

On Saturday, 25 February 2017 at 19:59:29 UTC, ikod wrote:

Hello,

I have a method for range:

struct Range {
immutable(ubyte[]) _buffer;
size_t _pos;

@property void popFront() pure @safe {
enforce(_pos < _buffer.length, "popFront from empty 
buffer");

_pos++;
}
}

I'd like to have @nogc here, but I can't because enforce() is 
non-@nogc.
I have a trick but not sure if it is valid, especially I don't 
know if optimization will preserve code, used for throwing:


import std.string;

struct Range {
immutable(ubyte[]) _buffer;
size_t  _pos;

this(immutable(ubyte[]) s) {
_buffer = s;
}
@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
auto _ = _buffer[$]; // throws RangeError
}
_pos++;
}
}

void main() {
auto r = Range("1".representation);
r.popFront();
r.popFront(); // throws
}

Is it ok to use it? Is there any better solution?

Thanks!


Found that I can use

@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
assert(0, "popFront for empty range");
}
_pos++;
}

which is both descriptive and can't be optimized out.


I made a test:

void main()
{
  assert(0);
}

it builds and doesn't throw if I compile with:
dmd -release

though it causes a segfault, what is probably a dmd bug. So I 
suppose it can be optimized out. And it isn't very discriptive, 
you probably throws the same AssertError for all errors. You can 
throw in @nogc code, you only have to allocate the exception not 
on the GC heap and free it after catching. I'm writing myself a 
library that is complete @nogc and I use exceptions this way:

- Allocate the exception
- throw
- catch
- free

A wrapper that unifies these 4 steps like enforce is pretty easy 
to implement.


Re: Recommend: IDE and GUI library

2017-02-25 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-02-24 23:44, XavierAP wrote:


And second question, is DWT the de facto standard for creating GUIs? Or
are there good competitors.


There's no de factor library for creating GUIs in D. If you want a 
native look and feel, DWT is a good option. If you want the application 
to look the same on all platforms, there might be other better suited 
alternatives.


--
/Jacob Carlborg


Re: trick to make throwing method @nogc

2017-02-25 Thread ikod via Digitalmars-d-learn

On Saturday, 25 February 2017 at 19:59:29 UTC, ikod wrote:

Hello,

I have a method for range:

struct Range {
immutable(ubyte[]) _buffer;
size_t _pos;

@property void popFront() pure @safe {
enforce(_pos < _buffer.length, "popFront from empty 
buffer");

_pos++;
}
}

I'd like to have @nogc here, but I can't because enforce() is 
non-@nogc.
I have a trick but not sure if it is valid, especially I don't 
know if optimization will preserve code, used for throwing:


import std.string;

struct Range {
immutable(ubyte[]) _buffer;
size_t  _pos;

this(immutable(ubyte[]) s) {
_buffer = s;
}
@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
auto _ = _buffer[$]; // throws RangeError
}
_pos++;
}
}

void main() {
auto r = Range("1".representation);
r.popFront();
r.popFront(); // throws
}

Is it ok to use it? Is there any better solution?

Thanks!


Found that I can use

@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
assert(0, "popFront for empty range");
}
_pos++;
}

which is both descriptive and can't be optimized out.



Re: Serializer class

2017-02-25 Thread Jacob Carlborg via Digitalmars-d-learn

On 2017-02-24 19:10, houdoux09 wrote:


The problem is that I can not retrieve the variables from the parent class.


Cast the value to the type of the base class and run it through the same 
function. You can have a look at the Orange serialization library [1].


[1] https://github.com/jacob-carlborg/orange

--
/Jacob Carlborg


trick to make throwing method @nogc

2017-02-25 Thread ikod via Digitalmars-d-learn

Hello,

I have a method for range:

struct Range {
immutable(ubyte[]) _buffer;
size_t _pos;

@property void popFront() pure @safe {
enforce(_pos < _buffer.length, "popFront from empty 
buffer");

_pos++;
}
}

I'd like to have @nogc here, but I can't because enforce() is 
non-@nogc.
I have a trick but not sure if it is valid, especially I don't 
know if optimization will preserve code, used for throwing:


import std.string;

struct Range {
immutable(ubyte[]) _buffer;
size_t  _pos;

this(immutable(ubyte[]) s) {
_buffer = s;
}
@property void popFront() pure @safe @nogc {
if (_pos >= _buffer.length ) {
auto _ = _buffer[$]; // throws RangeError
}
_pos++;
}
}

void main() {
auto r = Range("1".representation);
r.popFront();
r.popFront(); // throws
}

Is it ok to use it? Is there any better solution?

Thanks!



Re: Calling destroy on struct pointer

2017-02-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 25 February 2017 at 15:13:27 UTC, Radu wrote:


Here is sample on how destroy fails with a fwd decl error:

struct A
{
B b;
C c;
}

struct B
{
Wrap!A val;
}

struct C
{
Wrap!A val;
}

struct Wrap(T)
{

this(bool b)
{
t = cast(T*) malloc(T.sizeof);
}

~this()
{
destroy(*t);  // Error: struct app.A no size because of 
forward reference

}
T* t;
}


Thanks for the example.



Manual management fails now with the current construct, inst't 
it?


Hm, that's an issue you'd best take up to the bugtracker, I 
think. Maybe there's a way around that, but I don't know.




auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
|-- here a becomes null
assert(a is null); // :}
free(a); // Deallocate
|- free null...

You need to save a into a temp, then call free on temp.

A nice to have enhancement would be to return the destroyed 
pointer from destroy, enabling something like:


destroy(a).free();


Well, yes, but that is still backwards-incompatible and breaking 
user code is something I was under the impression was a big NO 
currently.


Re: Calling destroy on struct pointer

2017-02-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 25 February 2017 at 15:21:56 UTC, Radu wrote:


The correct way of doing it using deref would to look like:

struct A { int i; }

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct
destroy(*a);  // Destruct A
free(a); // Deallocate
destroy(a);  // Destruct A*
assert(a is null);


Right, I read the post and immediately failed to apply the new 
knowledge. Bad me, thanks for the correction.


Re: Calling destroy on struct pointer

2017-02-25 Thread Radu via Digitalmars-d-learn
On Saturday, 25 February 2017 at 13:18:21 UTC, Moritz Maxeiner 
wrote:
On Saturday, 25 February 2017 at 13:14:24 UTC, Moritz Maxeiner 
wrote:

---
struct A {}

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---


Sorry for double posting, I failed at copy-paste, here's the 
correct example:


---
struct A { int i; }

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---


The correct way of doing it using deref would to look like:

struct A { int i; }

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct
destroy(*a);  // Destruct A
free(a); // Deallocate
destroy(a);  // Destruct A*
assert(a is null);



Re: Calling destroy on struct pointer

2017-02-25 Thread Radu via Digitalmars-d-learn
On Saturday, 25 February 2017 at 13:14:24 UTC, Moritz Maxeiner 
wrote:

On Saturday, 25 February 2017 at 10:44:07 UTC, Radu wrote:
On Saturday, 25 February 2017 at 08:36:02 UTC, Ali Çehreli 
wrote:

On 02/25/2017 12:17 AM, Radu wrote:

> destroy(cc) -> does c = C.init
> destroy(*cc); -> calls the C dtor
>
> Is this by design? If so - how can I destroy and get the 
> dtor

called
> without dereferencing the pointer?

It's by design because setting a pointer to null can be 
considered as destroying the pointer. Dereferencing is the 
right way of destroying the object through the pointer.


I had added the following warning after somebody else was 
burnt by this feature. :)


  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

Ali


I think this is BAD. Why?

- it is one of those WAT?? moments that brings a RTFM slap to 
you. The defaults should not be surprising, and in this case 
straight dangerous as it can lead to leaks.


Unfortunately, I don't think it's viable to change destroy (see 
below), it would probably be better to cover this in the dlang 
tour (if it isn't already).


- it is not always possible to dereference the pointer, think 
some circular structures where deref would get you one of 
those fwd. declaration errors.


In the interest of learning, could you provide an example of 
such a case?


- the deprecated delete will call the dtor, destroy is suppose 
to replace delete - hence it should work the same.


AFAIK destroy isn't supposed to replace delete, since delete is 
destruction+deallocation and destroy is only destruction; and 
by that definition they cannot work the same: AFAIR multiple 
deletes are illegal (since that equals use after free), whereas 
destroy can be used on the same object as often as you want 
(the destructor will only be called the first time).




In my opinion destroy should do this:
- call dtor if the pointer type has one defined
- nullify the pointer

This is what I was expecting anyhow to happen...


This change would be backwards-incompatible and breaks user 
code, especially manual memory management:


---
struct A {}

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---

if destroy were to already nullify a, how were one supposed to 
deallocate a?


Here is sample on how destroy fails with a fwd decl error:

struct A
{
B b;
C c;
}

struct B
{
Wrap!A val;
}

struct C
{
Wrap!A val;
}

struct Wrap(T)
{

this(bool b)
{
t = cast(T*) malloc(T.sizeof);
}

~this()
{
destroy(*t);  // Error: struct app.A no size because of 
forward reference

}
T* t;
}

Manual management fails now with the current construct, inst't it?

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
|-- here a becomes null
assert(a is null); // :}
free(a); // Deallocate
|- free null...

You need to save a into a temp, then call free on temp.

A nice to have enhancement would be to return the destroyed 
pointer from destroy, enabling something like:


destroy(a).free();




Re: [Beginner]Variable length arrays

2017-02-25 Thread helxi via Digitalmars-d-learn
On Saturday, 25 February 2017 at 14:34:31 UTC, rikki cattermole 
wrote:

On 26/02/2017 3:31 AM, helxi wrote:
I am trying to create an array which has a user defined size. 
However

the following program is not compiling:

import std.stdio;

void main(){
write("Enter your array size: ");
int n;
readf(" %s", );
int[n] arr; //<-Error: variable input cannot be read at 
compile time

writeln(arr);
}

1. What's causing this?


T[X] is a static array, its size must be known at compile time.
Static arrays are passed around by value not by reference and 
generally get stored on the stack not the heap.


2. How can I get around this? I know I can always create a 
loop that

appends value 'n' times.


This is where you want a dynamic array, allocated on the heap 
at runtime.


T[] array;
array.length = n;


Thanks


Re: [Beginner]Variable length arrays

2017-02-25 Thread rikki cattermole via Digitalmars-d-learn

On 26/02/2017 3:31 AM, helxi wrote:

I am trying to create an array which has a user defined size. However
the following program is not compiling:

import std.stdio;

void main(){
write("Enter your array size: ");
int n;
readf(" %s", );
int[n] arr; //<-Error: variable input cannot be read at compile time
writeln(arr);
}

1. What's causing this?


T[X] is a static array, its size must be known at compile time.
Static arrays are passed around by value not by reference and generally 
get stored on the stack not the heap.



2. How can I get around this? I know I can always create a loop that
appends value 'n' times.


This is where you want a dynamic array, allocated on the heap at runtime.

T[] array;
array.length = n;


[Beginner]Variable length arrays

2017-02-25 Thread helxi via Digitalmars-d-learn
I am trying to create an array which has a user defined size. 
However the following program is not compiling:


import std.stdio;

void main(){
write("Enter your array size: ");
int n;
readf(" %s", );
int[n] arr; //<-Error: variable input cannot be read at 
compile time

writeln(arr);
}

1. What's causing this?
2. How can I get around this? I know I can always create a loop 
that appends value 'n' times.


Re: Pointers vs functional or array semantics

2017-02-25 Thread Ilya Yaroshenko via Digitalmars-d-learn
On Saturday, 25 February 2017 at 11:06:28 UTC, data pulverizer 
wrote:
I have noticed that some numerical packages written in D use 
pointer semantics heavily (not referring to packages that link 
to C libraries). I am in the process of writing code for a 
numerical computing library and would like to know whether 
there times when addressing an array using pointers conveys 
performance benefits over using D's array or functional 
semantics?


Pointers can behave like iterators, while to have an iterator on 
top of array you need to store array and index. This is slower 
and may disable vectorisation. Iterators semantic is required to 
build multidimensional random access ranges (ndslice). ndslice 
uses iterators heavily in its internals. Iterators semantic 
helped to create many multidimensional Phobos analogs in few 
dozens LOC, while Phobos has few hundreds LOC for the same 
functionality.


Phobos functional semantics disable vectorisation and other 
optimisations. mir.ndslice.topology [1], mir.ndslice.algorithm[1] 
and mir.functional[1] in combination with other Mir modules and 
packages can be used instead of Phobos functional utilities from 
std.algorithm, std.range, std.functional.


You may want to use the new ndslice [1]. Slice!(Contiguous, [1], 
T*) can replace T[].


[1] https://github.com/libmir/mir-algorithm


Re: Calling destroy on struct pointer

2017-02-25 Thread Moritz Maxeiner via Digitalmars-d-learn
On Saturday, 25 February 2017 at 13:14:24 UTC, Moritz Maxeiner 
wrote:

---
struct A {}

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---


Sorry for double posting, I failed at copy-paste, here's the 
correct example:


---
struct A { int i; }

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---


Re: Calling destroy on struct pointer

2017-02-25 Thread Moritz Maxeiner via Digitalmars-d-learn

On Saturday, 25 February 2017 at 10:44:07 UTC, Radu wrote:
On Saturday, 25 February 2017 at 08:36:02 UTC, Ali Çehreli 
wrote:

On 02/25/2017 12:17 AM, Radu wrote:

> destroy(cc) -> does c = C.init
> destroy(*cc); -> calls the C dtor
>
> Is this by design? If so - how can I destroy and get the dtor
called
> without dereferencing the pointer?

It's by design because setting a pointer to null can be 
considered as destroying the pointer. Dereferencing is the 
right way of destroying the object through the pointer.


I had added the following warning after somebody else was 
burnt by this feature. :)


  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

Ali


I think this is BAD. Why?

- it is one of those WAT?? moments that brings a RTFM slap to 
you. The defaults should not be surprising, and in this case 
straight dangerous as it can lead to leaks.


Unfortunately, I don't think it's viable to change destroy (see 
below), it would probably be better to cover this in the dlang 
tour (if it isn't already).


- it is not always possible to dereference the pointer, think 
some circular structures where deref would get you one of those 
fwd. declaration errors.


In the interest of learning, could you provide an example of such 
a case?


- the deprecated delete will call the dtor, destroy is suppose 
to replace delete - hence it should work the same.


AFAIK destroy isn't supposed to replace delete, since delete is 
destruction+deallocation and destroy is only destruction; and by 
that definition they cannot work the same: AFAIR multiple deletes 
are illegal (since that equals use after free), whereas destroy 
can be used on the same object as often as you want (the 
destructor will only be called the first time).




In my opinion destroy should do this:
- call dtor if the pointer type has one defined
- nullify the pointer

This is what I was expecting anyhow to happen...


This change would be backwards-incompatible and breaks user code, 
especially manual memory management:


---
struct A {}

auto a = cast (A*) malloc(A.sizeof); // Allocate
emplace(a, 42);  // Construct

destroy(a);  // Destruct
free(a); // Deallocate
---

if destroy were to already nullify a, how were one supposed to 
deallocate a?


Re: Pointers vs functional or array semantics

2017-02-25 Thread data pulverizer via Digitalmars-d-learn

On Saturday, 25 February 2017 at 11:15:53 UTC, ketmar wrote:

data pulverizer wrote:

I have noticed that some numerical packages written in D use 
pointer semantics heavily (not referring to packages that link 
to C libraries). I am in the process of writing code for a 
numerical computing library and would like to know whether 
there times when addressing an array using pointers conveys 
performance benefits over using D's array or functional 
semantics?


using `arr.ptr[n]` instead of `arr[n]` bypasses bounds 
checking. this may be diserable in tight loops (while disabling 
bounds checking globally is not).


but note that `foreach (int n; arr)` doesn't do bounds checking 
in loop too (afair), so you prolly better use `foreach` instead 
of pointers. this way your code will be fast, but still safe.


Thanks ketmar and thanks in advance to anyone else that comments.


Re: Pointers vs functional or array semantics

2017-02-25 Thread ketmar via Digitalmars-d-learn

data pulverizer wrote:

I have noticed that some numerical packages written in D use pointer 
semantics heavily (not referring to packages that link to C 
libraries). I am in the process of writing code for a numerical 
computing library and would like to know whether there times when 
addressing an array using pointers conveys performance benefits over 
using D's array or functional semantics?


using `arr.ptr[n]` instead of `arr[n]` bypasses bounds checking. this 
may be diserable in tight loops (while disabling bounds checking 
globally is not).


but note that `foreach (int n; arr)` doesn't do bounds checking in loop 
too (afair), so you prolly better use `foreach` instead of pointers. 
this way your code will be fast, but still safe.


Pointers vs functional or array semantics

2017-02-25 Thread data pulverizer via Digitalmars-d-learn
I have noticed that some numerical packages written in D use 
pointer semantics heavily (not referring to packages that link to 
C libraries). I am in the process of writing code for a numerical 
computing library and would like to know whether there times when 
addressing an array using pointers conveys performance benefits 
over using D's array or functional semantics?


Re: Calling destroy on struct pointer

2017-02-25 Thread Radu via Digitalmars-d-learn

On Saturday, 25 February 2017 at 08:36:02 UTC, Ali Çehreli wrote:

On 02/25/2017 12:17 AM, Radu wrote:

> destroy(cc) -> does c = C.init
> destroy(*cc); -> calls the C dtor
>
> Is this by design? If so - how can I destroy and get the dtor
called
> without dereferencing the pointer?

It's by design because setting a pointer to null can be 
considered as destroying the pointer. Dereferencing is the 
right way of destroying the object through the pointer.


I had added the following warning after somebody else was burnt 
by this feature. :)


  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

Ali


I think this is BAD. Why?

- it is one of those WAT?? moments that brings a RTFM slap to 
you. The defaults should not be surprising, and in this case 
straight dangerous as it can lead to leaks.
- it is not always possible to dereference the pointer, think 
some circular structures where deref would get you one of those 
fwd. declaration errors.
- the deprecated delete will call the dtor, destroy is suppose to 
replace delete - hence it should work the same.


In my opinion destroy should do this:
- call dtor if the pointer type has one defined
- nullify the pointer

This is what I was expecting anyhow to happen...



Re: Calling destroy on struct pointer

2017-02-25 Thread Ali Çehreli via Digitalmars-d-learn

On 02/25/2017 12:17 AM, Radu wrote:

> destroy(cc) -> does c = C.init
> destroy(*cc); -> calls the C dtor
>
> Is this by design? If so - how can I destroy and get the dtor called
> without dereferencing the pointer?

It's by design because setting a pointer to null can be considered as 
destroying the pointer. Dereferencing is the right way of destroying the 
object through the pointer.


I had added the following warning after somebody else was burnt by this 
feature. :)


  http://ddili.org/ders/d.en/memory.html#ix_memory.destroy

Ali



Calling destroy on struct pointer

2017-02-25 Thread Radu via Digitalmars-d-learn
I'm puzzled by the way destroy works when passed a pointer to a 
struct, observe:

--code.d--
int i;

struct C
{
this(ref int i)
{
++i;
ii = 
}

~this()
{
--(*ii);
}
int* ii;
}
unittest
{
C c = C(i);
C* cc = 
destroy(cc);
assert(i == 0); // dtor not called
destroy(*cc);
assert(i == 0); // dtor called
}
int main()
{

return 0;
}
--code.d--
destroy(cc) -> does c = C.init
destroy(*cc); -> calls the C dtor

Is this by design? If so - how can I destroy and get the dtor 
called without dereferencing the pointer?
Currently I resort to calling delete on the pointer so dtor gets 
called.