Thread overview | |||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 17, 2020 refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
---------------- 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mw | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mw | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mw | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Avrina | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to mw | 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 Re: refInt = ref int: how to achieve this? or is this a bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to MoonlightSentinel | 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];
}
|
Copyright © 1999-2021 by the D Language Foundation