Thread overview
Is there anyway to Deify the following code snippet?
April 15
I had assumed that ref keyword negated the use of * and & operators but when I try to use it, DMD is saying "only parameters, functions and `foreach` declarations can be `ref`". Fair enough. I thought that the * and & operator was for when interfacing with C/C++ code. Since this is entirely in D code, I thought there might be other options.

```
import std.stdio;

void main()
{

struct S {
    char  c;
    float f;
}

S*[int] aa;  // hold pointers to the struct S instances
S *d;

S u;
S v;

u.c = 'a';  u.f = 1.33;
aa[0] = &u;

v.c = 'z'; v.f = 3.14;
aa[1] = &v;


d = aa[0];

writeln("d.c = ", d.c, "  d.f = ", d.f);

d = null;

u.c = 'A';  u.f = 9.9;

d = aa[0];

writeln("d.c = ", d.c, "  d.f = ", d.f);
}
```
April 16
On Tuesday, 15 April 2025 at 21:06:30 UTC, WhatMeWorry wrote:
> I had assumed that ref keyword negated the use of * and & operators but when I try to use it, DMD is saying "only parameters, functions and `foreach` declarations can be `ref`". Fair enough. I thought that the * and & operator was for when interfacing with C/C++ code. Since this is entirely in D code, I thought there might be other options.

Nope, you're not missing anything. Using pointers is totally normal and idiomatic in D.
April 16

On Tuesday, 15 April 2025 at 21:06:30 UTC, WhatMeWorry wrote:

>

I had assumed that ref keyword negated the use of * and & operators but when I try to use it, DMD is saying "only parameters, functions and foreach declarations can be ref". Fair enough. I thought that the * and & operator was for when interfacing with C/C++ code. Since this is entirely in D code, I thought there might be other options.

These are accurate observations! As you know, classes can be more practical in the programming world. Have you also tried looking at the topic from the following perspective?

class S
{
    char  c;
    float f;

    override string toString()
        => text(i"[c = $(c), f = $(f)]");
}

import std.conv, std.stdio;
void main()
{
    S[int] aa;  // int -> S as an associative array (not by address but by direct reference)

    auto u = new S();
    u.c = 'a';
    u.f = 1.33;
    aa[0] = u;

    auto v = new S();
    v.c = 'z';
    v.f = 3.14;
    aa[1] = v;
	
    aa.writeln;

    S d = aa[0];
    d.writeln;

    d = null; // d no longer points to the object, but aa[0] still does

    // let's change the u object:
    u.c ^= ' '; // magic!
    u.f *= 3;
    assert(d is null);

    d = aa[0];
    d.writeln;
    assert(d is null);

    aa.writeln;
} /* Prints:
[0:[c = a, f = 1.33], 1:[c = z, f = 3.14]]
[c = a, f = 1.33]
[c = A, f = 3.99]
[0:[c = A, f = 3.99], 1:[c = z, f = 3.14]]
//*/

SDB@79

April 16
On Wednesday, 16 April 2025 at 01:44:33 UTC, Paul Backus wrote:
> Nope, you're not missing anything. Using pointers is totally normal and idiomatic in D.

That said, I try to code under @safe when I can, and let the compiler guide me clear of a whole class of C-type potential bugs.

Andy

April 16
On Wed, Apr 16, 2025 at 04:23:43AM +0000, Andy Valencia via Digitalmars-d-learn wrote:
> On Wednesday, 16 April 2025 at 01:44:33 UTC, Paul Backus wrote:
> > Nope, you're not missing anything. Using pointers is totally normal and idiomatic in D.
> 
> That said, I try to code under @safe when I can, and let the compiler guide me clear of a whole class of C-type potential bugs.
[...]

Pointers can be used perfectly fine in @safe. Just not unsafe operations like pointer arithmetic.


T

-- 
Notwithstanding the eloquent discontent that you have just respectfully expressed at length against my verbal capabilities, I am afraid that I must unfortunately bring it to your attention that I am, in fact, NOT verbose.
April 16

On Wednesday, 16 April 2025 at 14:48:04 UTC, H. S. Teoh wrote:

>

Pointers can be used perfectly fine in @safe. Just not unsafe operations like pointer arithmetic.

So, apart from stdout.flush(), is it perfect to use the following code with @safe:

import std.stdio, std.random;
import std.random : ups = unpredictableSeed;
import core.stdc.stdlib : rand, RAND_MAX;

alias T = double; // float;
enum N = int.max; // long.max;
auto phobosRandom()
  => cast(T)Random(ups).front / N;

auto stdlibRandom()
  => cast(T)rand() / RAND_MAX;

@safe:
struct RandGroup
{
    string name;
    T function() gene;
    T up = 0.9;
    T down = 0.1;
} /* Prints:

0.10826: Testing uniform...
0.493747: Testing Phobos...
0.840188: Testing StdLib...
//*/

void main()
{
    RandGroup[3] funcs = [
    {
          name: "uniform",
          gene: () => uniform(0.0, 1.0),
          //down: 0.01, up: 0.02
    }, {

          name: "Phobos",
          gene: &phobosRandom,

    }, {

          name: "StdLib",
          gene: &stdlibRandom,

     },
  ];
  
  foreach (func; funcs)
  {
    with(func)
    {
      auto generate = gene();
      generate.write(": ");
      writeln("Testing ", name, "...");
      //stdout.flush(); // error
    }
  }
}

SDB@79

April 17
On Wednesday, April 16, 2025 8:48:04 AM MDT H. S. Teoh via Digitalmars-d-learn wrote:
> On Wed, Apr 16, 2025 at 04:23:43AM +0000, Andy Valencia via Digitalmars-d-learn wrote:
> > On Wednesday, 16 April 2025 at 01:44:33 UTC, Paul Backus wrote:
> > > Nope, you're not missing anything. Using pointers is totally normal and idiomatic in D.
> >
> > That said, I try to code under @safe when I can, and let the compiler guide me clear of a whole class of C-type potential bugs.
> [...]
>
> Pointers can be used perfectly fine in @safe. Just not unsafe operations like pointer arithmetic.

Also, taking the address of stuff like local variables is @system, because it's not safe if the pointer escapes. But yeah, in general, using pointers is @safe outside of pointer arithmetic. At that point, there isn't much difference between a pointer and a reference. They just point to an object. It's escaping which is potentially a problem (which ref is stricter about) and pointer arithmetic (which can't be done with ref). Basically, as long as what you're doing with a pointer is what can be done with a reference, then it's @safe.

- Jonathan M Davis