Re: Memory leak issue between extern (c) and D function

2023-04-16 Thread Guillaume Piolat via Digitalmars-d-learn

On Friday, 14 April 2023 at 17:31:02 UTC, backtrack wrote:

however the memory is not releasing.


With the D GC, your object can have three state:

  - reachable by GC. If D code can see the reference, then it's 
"alive", kept alive by GC scanning. The GC finds the reference 
and doesn't touch it. This is the invariant that you need to 
maintain when interacting with C.


  - unreachable by GC and thus at a risk of being reclaimable at 
next GC collect.

This happens when all your references are null.
If you want immediate destructor, call .destroy() before 
nulling your references so that the object can't be scanned. By 
calling destroy() on all your objects manually, you can reach 
destruction determinism.


  - non-existing, memory has been reclaimed. You don't 
necessarily need to do that with __delete, this should be very 
rare even. If the references to the object are null, then their 
destructor will eventually be called if it wasn't already with 
.destroy, the memory eventually reclaimed. Usually you don't need 
to care about that state.




Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Skippy via Digitalmars-d-learn

On Sunday, 16 April 2023 at 08:38:55 UTC, Ali Çehreli wrote:

On 4/16/23 00:46, Skippy wrote:

> I wish D had value type classes as well.

That cannot work due to the slicing problem.

C++ cannot have value type classes either for the same reason. 
The difference there is that the enforcement is by guidelines 
(e.g. "never pass class objects by value to functions", not by 
language).


If you want class objects on the stack, you have two options:

- The scope keyword

- The scoped template from Phobos

Ali


IMO, there is no need to 'force' reference semantics on the 
example provided (i.e the slicing problem does not apply here).


I was under the impression scope (the keyword) was being 
deprecated?


I could have used a struct of course, but my mental model of a 
struct is a C-like struct, not a C++ like struct. I like that 
mental model - which is the reason why I like C++'s value type 
classes.


Then there is the issue of the D compiler assigning a 'default 
value' to an object variable that hasn't yet been assigned a 
value: Object o;


But.. that's a separate discussion.


Re: Returning a reference to be manipulated

2023-04-16 Thread Dennis via Digitalmars-d-learn

On Saturday, 15 April 2023 at 21:00:01 UTC, kdevel wrote:

On Saturday, 15 April 2023 at 15:50:18 UTC, Dennis wrote:

[...]
care about the type / mutability of the pointer.


Returning `i`'s address in a long does not trigger the escape 
detector:


It doesn't care about the type of pointer, but it does care about 
whether the type is/has a pointer in the first place. `T*`, 
`T[]`, `K[V]` (Associative arrays), `class`, `function`, 
`delegate` are pointers. Static arrays and structs depend on what 
they contain. Basic types such as `long` are not pointers, so 
lifetime checking doesn't apply.




Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Ali Çehreli via Digitalmars-d-learn

On 4/16/23 00:46, Skippy wrote:

> I wish D had value type classes as well.

That cannot work due to the slicing problem.

C++ cannot have value type classes either for the same reason. The 
difference there is that the enforcement is by guidelines (e.g. "never 
pass class objects by value to functions", not by language).


If you want class objects on the stack, you have two options:

- The scope keyword

- The scoped template from Phobos

Ali



Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 April 2023 at 07:46:53 UTC, Skippy wrote:



I wish D had value type classes as well.


I like the distinction between class and struct in D. It 
encourages you to think harder about how you intend to use your 
types. In C++, there may as well only be one or the other; the 
distinction is so small as to be meaningless.


Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Skippy via Digitalmars-d-learn

On Sunday, 16 April 2023 at 06:39:17 UTC, Mike Parker wrote:


`t1` is default-initialized, so it's null.
test t1, t2 = new test();


silly me. I should have picked that up myself. thanks.

Ditto for t3. Classes are reference objects, not value objects, 
so you must explicitly instantiate instances if you want them 
to be non-null.

test t3;


again, silly me. I should have picked that up myself. thanks.

I wish D had value type classes as well.




Re: Cannot get this C++ example migrated to D

2023-04-16 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 16 April 2023 at 05:58:39 UTC, Skippy wrote:

These lines aren't necessary:


// ??
int counter;

// ??
static this()
{
counter = test.objCnt;
}



`t1` is default-initialized, so it's null.

test t1, t2 = new test();


Ditto for t3. Classes are reference objects, not value objects, 
so you must explicitly instantiate instances if you want them to 
be non-null.

test t3;


The modified code:

```d
class test
{
  private:
int objNo;
static int objCnt;

  public:
this()
{
objNo = ++objCnt;
}

~this()
{
--objCnt;
}

void printObjNumber()
{
writefln("object number : %s", objNo);
}

static void printObjCount()
{
writefln("count: %s", objCnt);
}
}


int main()
{
test t1 = new test(), t2 = new test();

test.printObjCount();

test t3 = new test;
test.printObjCount();

t1.printObjNumber();
t2.printObjNumber();
t3.printObjNumber();

return 0;
}
```


Cannot get this C++ example migrated to D

2023-04-16 Thread Skippy via Digitalmars-d-learn

Anyone wanna try converting this C++ example to D?

(I tried, but getting nowhere.. so far).

// --- C++ example - working -
#include 
using std::cout;

class test
{
  private:
int objNo;
static int objCnt;

  public:
test()
{
objNo = ++objCnt;
}

~test()
{
--objCnt;
}

void printObjNumber(void)
{
cout << "object number :" << objNo << "\n";
}

static void printObjCount(void)
{
cout << "count:" << objCnt << "\n";
}
};

int test::objCnt;

int main()
{
test t1, t2;
test::printObjCount(); // 2

test t3;
test::printObjCount(); // 3

t1.printObjNumber(); // object number :1
t2.printObjNumber(); // object number :2
t3.printObjNumber(); // object number :3

return 0;
}
// ---

// D code .. not working yet --
module example;
import std:writefln;

class test
{
  private:
int objNo;
static int objCnt;

  public:
this()
{
objNo = ++objCnt;
}

~this()
{
--objCnt;
}

void printObjNumber()
{
writefln("object number : %s", objNo);
}

static void printObjCount()
{
writefln("count: %s", objCnt);
}
}

// ??
int counter;

// ??
static this()
{
counter = test.objCnt;
}

int main()
{
test t1, t2 = new test();

test.printObjCount();

test t3;
test.printObjCount();

t1.printObjNumber();
t2.printObjNumber();
t3.printObjNumber();

return 0;
}
//