Jump to page: 1 24  
Page
Thread overview
refInt = ref int: how to achieve this? or is this a bug?
Jun 17, 2020
mw
Jun 17, 2020
mw
Jun 17, 2020
mw
Jun 17, 2020
Avrina
Jun 17, 2020
mw
Jun 17, 2020
MoonlightSentinel
Jun 17, 2020
MoonlightSentinel
Jun 17, 2020
mw
Jun 17, 2020
MoonlightSentinel
Jun 17, 2020
mw
Jun 17, 2020
Stanislav Blinov
Jun 17, 2020
mw
Jun 17, 2020
Stanislav Blinov
Jun 17, 2020
mw
Jun 18, 2020
mw
Jun 18, 2020
Paul Backus
Jun 18, 2020
Stanislav Blinov
Jun 18, 2020
mw
Jun 18, 2020
mw
Jun 18, 2020
Stanislav Blinov
Jun 18, 2020
mw
Jun 18, 2020
mw
Jun 18, 2020
Stanislav Blinov
Jun 18, 2020
H. S. Teoh
Jun 19, 2020
Stanislav Blinov
Jun 19, 2020
H. S. Teoh
Jun 17, 2020
Stanislav Blinov
Jun 17, 2020
Ali Çehreli
Jun 17, 2020
mw
Jun 17, 2020
Stanislav Blinov
Jun 17, 2020
mw
Jun 17, 2020
Stanislav Blinov
Jun 17, 2020
mw
June 17, 2020
----------------
import std.stdio;

alias refInt = ref int;

void f(refInt i) {
  i = 456;
}

void main() {
  int i = 123;
  writeln(i);
  f(i);
  writeln(i);
}
----------------

$ $DMD/windows/bin64/rdmd.exe reft.d
123
123

$ $LDC/bin/rdmd  reft.d
123
123

How to achieve this typdef/alias that what I want?

Thanks.
June 17, 2020
On 6/17/20 4:38 PM, mw wrote:
> ----------------
> import std.stdio;
> 
> alias refInt = ref int;
> 
> void f(refInt i) {
>    i = 456;
> }
> 
> void main() {
>    int i = 123;
>    writeln(i);
>    f(i);
>    writeln(i);
> }
> ----------------
> 
> $ $DMD/windows/bin64/rdmd.exe reft.d
> 123
> 123
> 
> $ $LDC/bin/rdmd  reft.d
> 123
> 123
> 
> How to achieve this typdef/alias that what I want?

It's not possible in this way. ref is a storage class and not part of the type.

Essentially, your alias statement becomes:

alias refInt = int;

Which in itself is somewhat of a "feature", as storage classes that do not apply are ignored. Some may consider it a bug, but I haven't seen anyone attempt something like what you have, it sure seems like the compiler should complain.

-Steve
June 17, 2020
On 6/17/20 1:38 PM, mw wrote:

> alias refInt = ref int;


(Aside: I think this thread should be on the 'learn' forum.)

I've just come up with the following struct just to compile the code. It works but as you see with need for refInt(i) inside main, constructors are not called automatically in D. (Hence your thread. :) )

import std.stdio;

struct refInt {
  int * p;

  this(ref int i) {
    this.p = &i;
  }

  ref int reference() {
    return *p;
  }

  alias reference this;

  auto opAssign(int i) {
    reference() = i;
    return this;
  }
}

void f(refInt i) {
  i = 456;
}

void main() {
  int i = 123;
  writeln(i);
  f(refInt(i));
  writeln(i);
}

Ali
June 17, 2020
On Wednesday, 17 June 2020 at 20:47:59 UTC, Steven Schveighoffer wrote:
> On 6/17/20 4:38 PM, mw wrote:
> It's not possible in this way. ref is a storage class and not part of the type.
>
> Essentially, your alias statement becomes:
>
> alias refInt = int;
>
> Which in itself is somewhat of a "feature", as storage classes that do not apply are ignored. Some may consider it a bug, but I haven't seen anyone attempt something like what you have, it sure seems like the compiler should complain.

I'm trying to typedef a PushT here:

https://github.com/mingwugmail/liblfdsd/blob/master/liblfds.dpp#L52

The C interface only accept void*, so I need different PushT type for different D type (basic type int|double, ..., struct, class, stirng|array).

Without be able to `alias PushT = ref T`, it's hard to define this func:

https://github.com/mingwugmail/liblfdsd/blob/master/liblfds.dpp#L72

bool push(PushT value) {
  ...
}

Any work-around? or suggestions how to structure the D code?

June 17, 2020
On Wednesday, 17 June 2020 at 21:01:53 UTC, Ali Çehreli wrote:
> On 6/17/20 1:38 PM, mw wrote:
> (Aside: I think this thread should be on the 'learn' forum.)

That's my initially thought, but then I realized this could be a D bug, or a feature request.

> struct refInt {...}

Yes, I know there are work-around, but for my usage:

https://github.com/mingwugmail/liblfdsd/blob/master/liblfds.dpp#L52

all these work-around are too heavy, a verbatim typedef in my question is the most succinct way to be used.

Sigh, looks like it's not supported at this time, guess I have to write more `static if`s.

June 17, 2020
On Wednesday, 17 June 2020 at 20:47:59 UTC, Steven Schveighoffer wrote:
> Essentially, your alias statement becomes:
>
> alias refInt = int;
>
> Which in itself is somewhat of a "feature", as storage classes that do not apply are ignored. Some may consider it a bug, but I haven't seen anyone attempt something like what you have, it sure seems like the compiler should complain.

I would consider it a bug, *even* C++ can handle this better :-)  i.e. no surprise to the programmer.

cat reft.cpp
----------------------
#include <stdio.h>

typedef int& refInt;

void f(refInt i) {
  i = 456;
}

int main() {
  int i = 123;
  printf("%d\n", i);
  f(i);
  printf("%d\n", i);
}
----------------------

$ make reft
g++     reft.cpp   -o reft


$ ./reft
123
456


June 17, 2020
On Wednesday, 17 June 2020 at 21:27:01 UTC, mw wrote:
> On Wednesday, 17 June 2020 at 20:47:59 UTC, Steven Schveighoffer wrote:
>> Essentially, your alias statement becomes:
>>
>> alias refInt = int;
>>
>> Which in itself is somewhat of a "feature", as storage classes that do not apply are ignored. Some may consider it a bug, but I haven't seen anyone attempt something like what you have, it sure seems like the compiler should complain.
>
> I would consider it a bug, *even* C++ can handle this better :-)  i.e. no surprise to the programmer.
>
> cat reft.cpp
> ----------------------
> #include <stdio.h>
>
> typedef int& refInt;
>
> void f(refInt i) {
>   i = 456;
> }
>
> int main() {
>   int i = 123;
>   printf("%d\n", i);
>   f(i);
>   printf("%d\n", i);
> }
> ----------------------
>
> $ make reft
> g++     reft.cpp   -o reft
>
>
> $ ./reft
> 123
> 456

It's not a bug, it is purposefully designed to be that way.

Just like you can't do ref variables.


void main() {
   int a;
   int& b = a; // ok C++
   ref int c = a; // not valid D
}


You can do something like this instead, not sure what you are trying to do tho. Could just be easier to put a separate function in the `static if` that you are trying to define the ref type in instead.


import std.stdio;

void foo(T)(auto ref T v) if (is(T : int) == __traits(isRef, v)) {
    writeln(__traits(isRef, v) ? "by ref" : "by value");
}

void main() {
	int a;
    foo(a); // by ref
    // foo(10); // error by value

    float b;
    // foo(b); // error by ref
    foo(10.0f); // by value
}
June 17, 2020
On Wednesday, 17 June 2020 at 21:49:29 UTC, Avrina wrote:
> void foo(T)(auto ref T v) if (is(T : int) == __traits(isRef, > v)) {

Thanks for the suggestion.

Yes, that what I mean by: "guess I have to write more `static if`s."

That is ugly.


My thought is that: pointer and reference are all types of its own right:

typedef `int*` is ptr in C++
typedef `int&` is ref in C++

and can you see the beauty of this symmetry?  :-)


In D, alias can correctly treat int* as pointer type, but treat `ref int` as `int`, this break the symmetry

alias `int*`    is       ptr  in D
alias `ref int` becomes *int* in D

can you see the visual ugliness of this? :-) not even to mention the semantic ugliness:

compiler error on g(), not on f():
---------------------------
alias refInt = ref int;
alias ptrInt =     int*;

void f(refInt i) {
  i = 456;
}

void g(ptrInt i) {
}

void main() {
  int i = 123;
  writeln(i);  // 123
  f(i);
  writeln(i);  // 123! again

  g(i);   // Error: function `reft.g(int* i)` is not callable using argument types `(int)`
}
---------------------------

June 17, 2020
On Wednesday, 17 June 2020 at 22:09:35 UTC, mw wrote:
> and can you see the beauty of this symmetry?  :-)

Try

int main()
{
    typedef int* ptrInt;
    ptrInt arr;

    typedef int& refInt;
    refInt[] arr2;
}
June 17, 2020
On Wednesday, 17 June 2020 at 22:15:08 UTC, MoonlightSentinel wrote:
> On Wednesday, 17 June 2020 at 22:09:35 UTC, mw wrote:

On Wednesday, 17 June 2020 at 22:15:08 UTC, MoonlightSentinel wrote:
Wrong code, this was the intended code:
int main()
{
    typedef int* ptrInt;
    ptrInt arr[5];

    typedef int& refInt;
    refInt arr2[5];
}
« First   ‹ Prev
1 2 3 4