Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

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:


```
long foo (long s, return ref int i)
{
   s = cast (long) 
   return s;
}

auto bar ()
{
   int i;
   long s;
   return foo (s, i);
}
```

dmd compiles this without complaints.



Re: class variable initialization

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

On 4/15/23 09:06, NonNull wrote:

>> struct Wrapper
>> {
>>Object x = new Object();
>>alias x this;
>> }

> Amazing, was this always so?

At least for a long time. However, every Wrapper object will have a 
pointer to that single shared object.


If you think that cost is unnecessary, you can have a static variable:

struct Wrapper
{
   static Object x;
   alias x this;
}

static this() {
Wrapper.x = new Object();
}

However, because such data are thread-local by-default, not the entire 
class, but each thread will have a copy that variable.


When you want a single class variable for all threads, then it must be 
defined as shared:


struct Wrapper
{
   shared static Object x;
   alias x this;
}

shared static this() {
Wrapper.x = new Object();
}

void foo(shared Object o)
{
   assert(o !is null);
}

Note how foo's interface had to be changed as well. And of course you 
may have to provide thread synchronization when that variable needs to 
be mutated at run time.


Ali



Re: How to use @safe when a C library integration needed

2023-04-15 Thread Leonardo via Digitalmars-d-learn

On Friday, 14 April 2023 at 16:19:22 UTC, Paul Backus wrote:

On Friday, 14 April 2023 at 14:10:41 UTC, Leonardo wrote:

[...]


No, there isn't. C is an unsafe language, so if you want to 
call C from `@safe` code, you have to do the work to make sure 
that each individual call is `@safe`.


[...]


Thanks for your response.


Re: class variable initialization

2023-04-15 Thread NonNull via Digitalmars-d-learn
On Saturday, 15 April 2023 at 15:47:40 UTC, Steven Schveighoffer 
wrote:

You can construct objects at compile time.

If I understand your question properly:

```d
struct Wrapper
{
   Object x = new Object();
   alias x this;
}

void foo(Object o)
{
   assert(o !is null);
}

void main()
{
   Wrapper w;
   foo(w);
}
```

-Steve


Amazing, was this always so?





Re: Returning a reference to be manipulated

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

On Saturday, 15 April 2023 at 14:33:52 UTC, kdevel wrote:

Does that make sense?


Whether it makes sense is subjective, but it is by design. Escape 
analysis considers every  pointer the same, it doesn't care about 
the type / mutability of the pointer. In `@system` / `@trusted` 
code, you could coerce `i` to become a string and return it:


```D
string foo(string s, return ref int i)
{
   return (cast(immutable char*) )[0..4];
}
```



Re: class variable initialization

2023-04-15 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/15/23 7:05 AM, NonNull wrote:
I want a way to default initialize a class variable to a default object 
(e.g. by wrapping it in a struct, because initialization to null cannot 
be changed directly). Such a default object is of course not available 
at compile time which seems to make this impossible. Can this be done in 
some way?


You can construct objects at compile time.

If I understand your question properly:

```d
struct Wrapper
{
   Object x = new Object();
   alias x this;
}

void foo(Object o)
{
   assert(o !is null);
}

void main()
{
   Wrapper w;
   foo(w);
}
```

-Steve


Re: class variable initialization

2023-04-15 Thread NonNull via Digitalmars-d-learn

On Saturday, 15 April 2023 at 14:17:19 UTC, Vijay Nayar wrote:
I believe if you do initialization at the class declaration 
level, then every instance of the class shares the same 
instance, e.g.:


```
class Var {}

class MyClass {
  Var var = new Var();
}

void main() {
  MyClass c1 = new MyClass();
  MyClass c2 = new MyClass();
  assert(c1.var is c2.var);
}
```


I should have made it clear that want a single shared default 
object. Your code above solves that problem. So does


```
Var defaultObj;
static this() { defaultObj = new Var(); }
```

By wrapping the new variable and the constructor call to 
initialize it in MyClass, you eliminate the need to call the 
constructor, which is what I want, but now you add the need to 
call another constructor. So for my purposes this is just moving 
the problem of null to another place.




Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

On Saturday, 15 April 2023 at 14:10:57 UTC, Dennis wrote:

[...]
This adds complexity, just to add some 'intermediate' safety 
between `@system` and `@safe` in a few cases. It's better to 
keep the rules simple and consistent.


Thanks for the answer! While playing around with return ref I 
came across this:


```
string foo (string s, return ref int i)
{
   return s;
}

auto bar ()
{
   int i;
   string s;
   return foo (s, i);
}
```

```
$ dmd rr.d
rr.d(10): Error: returning `foo(s, i)` escapes a reference to 
local variable `i`

```

Does that make sense?


Re: Returning a reference to be manipulated

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

On Saturday, 15 April 2023 at 14:10:57 UTC, Dennis wrote:
This adds complexity, just to add some 'intermediate' safety 
between `@system` and `@safe` in a few cases. It's better to 
keep the rules simple and consistent.


To quote my past self:


There used to be different rules for lifetime errors in all of 
these:

- explicit `@system` functions
- `@system` by default functions (yes, [they were 
special](https://issues.dlang.org/show_bug.cgi?id=19873))

- inferred functions
- `@safe` functions
- `@trusted` functions

It was really complex and confusing, and I've worked on 
simplifying it such that all lifetime errors are safety 
violations like any other. The only exception is directly 
returning a dangling pointer to a stack variable, which is just 
an error even in @system code ([issue 
19873](https://issues.dlang.org/show_bug.cgi?id=19873)). I 
don't want to go back to more special cases, especially with 
the dip1000 by default transition which is complex enough as is.


https://forum.dlang.org/post/nzotevvzvbpqscfxs...@forum.dlang.org



Re: class variable initialization

2023-04-15 Thread Vijay Nayar via Digitalmars-d-learn

On Saturday, 15 April 2023 at 14:05:17 UTC, NonNull wrote:
I want a way to default initialize a class variable to a 
default object (e.g. by wrapping it in a struct, because 
initialization to null cannot be changed directly). Such a 
default object is of course not available at compile time which 
seems to make this impossible. Can this be done in some way?


Assuming you want a default object that is unique per class 
instance rather than shared among all instances of the same 
class, then I think the constructor might be where you want to 
initialize such a member.


E.g.
```
class Var {
  int val;
  this(int val) {
this.val = val;
  }
}

class MyClass {
  Var var;

  this() {
var = new Var(3);
  }
}
```

I believe if you do initialization at the class declaration 
level, then every instance of the class shares the same instance, 
e.g.:


```
class Var {}

class MyClass {
  Var var = new Var();
}

void main() {
  MyClass c1 = new MyClass();
  MyClass c2 = new MyClass();
  assert(c1.var is c2.var);
}
```


Re: Returning a reference to be manipulated

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

On Saturday, 15 April 2023 at 13:20:09 UTC, kdevel wrote:
Under which circumstances is it a mistake to insert the 
`return` at the indicated position? If there are none why can't 
it be done implicitly (automatically)?


It could be done in the easy example you posted, but generalizing 
it is harder.


When importing a module, the compiler currently doesn't need to 
analyze function bodies to get the signature of regular 
(non-auto/template) functions, which would have to change. 
Programmers can also currently rely on the fact that the 
signature they see is the signature they get, but not any longer.


The identity function is really simple, but as soon as control 
flow (if-statements) come into play, the annotations and their 
inference become a conservative approximation, which might give 
false positives in `@system` code. There would need to be a 
second system, one which assumes the best instead of assuming the 
worst.


This adds complexity, just to add some 'intermediate' safety 
between `@system` and `@safe` in a few cases. It's better to keep 
the rules simple and consistent.




class variable initialization

2023-04-15 Thread NonNull via Digitalmars-d-learn
I want a way to default initialize a class variable to a default 
object (e.g. by wrapping it in a struct, because initialization 
to null cannot be changed directly). Such a default object is of 
course not available at compile time which seems to make this 
impossible. Can this be done in some way?


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn
On Saturday, 15 April 2023 at 13:24:52 UTC, Richard (Rikki) 
Andrew Cattermole wrote:

On 16/04/2023 1:20 AM, kdevel wrote:
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
It was bad analysis by the compiler, which has since been 
corrected.


It should have been applied only to @safe code.


But why is the @unsafe programmer now left unprotected in 
cases like this


```
ref int foo (ref int i)
//   `--- automatically insert `return` here?
{
    return i;
}
```

where the compiler recognizes that the function returns a ref 
parameter?


Under which circumstances is it a mistake to insert the 
`return` at the indicated position? If there are none why 
can't it be done implicitly (automatically)?


@system (which is currently the default, there is a strong 
desire to change this), does no safety checks.


When I insert `return` before `ref int` and compile the code dmd 
says


```
returnref2.d(9): Error: returning `foo(i)` escapes a reference to 
local variable `i`

```

Isn't this a safety check? (The code does not contain any `@`.)

My question was if it is problematic if dmd inserted a `return` 
before any `ref` parameter a function returns.


Did the removed code which checked for returning ref parameters 
have false positives?


If not again my question: Under what circumstances would it be a 
mistake to insert `return` before the respective `ref` parameter?






Re: Returning a reference to be manipulated

2023-04-15 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

On 16/04/2023 1:20 AM, kdevel wrote:
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) Andrew 
Cattermole wrote:

It was bad analysis by the compiler, which has since been corrected.

It should have been applied only to @safe code.


But why is the @unsafe programmer now left unprotected in cases like this

```
ref int foo (ref int i)
//   `--- automatically insert `return` here?
{
    return i;
}
```

where the compiler recognizes that the function returns a ref parameter?

Under which circumstances is it a mistake to insert the `return` at the 
indicated position? If there are none why can't it be done implicitly 
(automatically)?


@system (which is currently the default, there is a strong desire to 
change this), does no safety checks.


You are on your own to do whatever unsafe thing you want.

If you want safety checks, use @safe.


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn
On Saturday, 15 April 2023 at 12:45:31 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
It was bad analysis by the compiler, which has since been 
corrected.


It should have been applied only to @safe code.


But why is the @unsafe programmer now left unprotected in cases 
like this


```
ref int foo (ref int i)
//   `--- automatically insert `return` here?
{
   return i;
}
```

where the compiler recognizes that the function returns a ref 
parameter?


Under which circumstances is it a mistake to insert the `return` 
at the indicated position? If there are none why can't it be done 
implicitly (automatically)?


Re: Returning a reference to be manipulated

2023-04-15 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

It was bad analysis by the compiler, which has since been corrected.

It should have been applied only to @safe code.


Re: Returning a reference to be manipulated

2023-04-15 Thread kdevel via Digitalmars-d-learn

On Friday, 14 April 2023 at 11:18:21 UTC, Dennis wrote:

On Friday, 14 April 2023 at 10:31:58 UTC, kdevel wrote:

But in fact it is returned unless it is `return ref`.


When using `return ref`, `return scope`, `scope` etc., you 
should be using the latest compiler and annotate functions you 
want checked with `@safe`.


We are writing at cross puroposes. I am not asking how I could 
help the compiler. My point is: I have code from 2019 which 
produced a deprecation warning


```
returnref2.d(3): Deprecation: returning i escapes a reference to 
parameter i, perhaps annotate with return

```

when compiled with with the compiler of that time (v2.093.1). 
When I use a recent compiler (v2.102.2) the code compiles without 
any complaints. I am asking myself what has deprecacted? I mean: 
Deprecation notes are built into the compiler in order to enable 
a "soft landing" for a scheduled breaking change. But I cannot 
see any breaking change at all regarding the code example in


https://forum.dlang.org/post/iysfuhjwyalnnmalb...@forum.dlang.org



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

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

On 4/13/23 20:50, backtrack wrote:

>  mystruct* getmystruct()
>  {
>  mystruct* mystruct = cast(mystruct*)malloc(mystruct.sizeof);
>  return mystruct;
>
>  }

There must be a corresponding function to do the cleaning:

void freemystruct(mystruct* ptr) {
free ptr;
}

You have to make sure on the D side that freemystruct() is called once 
for each getmystruct().


I have the following presentation that covers similar concepts:

  https://www.youtube.com/watch?v=FNL-CPX4EuM

I think this point is most relevant:

  https://www.youtube.com/watch?v=FNL-CPX4EuM=1833s

Ali