June 17, 2020
On Wednesday, 17 June 2020 at 21:20:00 UTC, mw wrote:
> 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.

This is not a bug, this is by design.

Also, you're trying to escape a pointer to arbitrary non-`shared` data residing on the stack into some global, shared, storage. I.e. (a) to not cause UB, you will need to make sure the consumer gets the data before you go out of scope, which defeats the purpose of this lock-free queue. And (b) to not cause UB, you will need to make sure consumer does not access the data concurrently with the producer.

With that taken into account, if you do want to be escaping pointers, just escape pointers.
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:
>> and can you see the beauty of this symmetry?  :-)
>
> Try
>
> int main()
> {
>     typedef int* ptrInt;
>     ptrInt arr;
>
>     typedef int& refInt;
>     refInt[] arr2;
> }

That's the semantics of reference: you cannot define a ref variable out of air. The equivalent D code cannot be compiled either.

We are talking about pass either `ptr` or `ref` to other functions here.

June 17, 2020
On Wednesday, 17 June 2020 at 22:19:28 UTC, Stanislav Blinov wrote:
>
> This is not a bug, this is by design.
>
> Also, you're trying to escape a pointer to arbitrary non-`shared` data residing on the stack into some global, shared, storage. I.e. (a) to not cause UB, you will need to make sure the consumer gets the data before you go out of scope, which defeats the purpose of this lock-free queue. And (b) to not cause UB, you will need to make sure consumer does not access the data concurrently with the producer.
>
> With that taken into account, if you do want to be escaping pointers, just escape pointers.

This discussion is not about this particular usage in that particular queue (either shared/lock free or not). Even with a plain dummy queue, the user can do whatever s/he want with the queue, e.g. push a stack var, and pop it when that stack is gone :-). The queue object has no control of this, again regardless of what kind of the queue it is. It's the programmers' responsibility to make sure the push/pop usage is right.


Here we are discussing how to write:

-- f(pass by value) and
-- f(pass by ref)

in a simple and straight forward way.

June 17, 2020
On Wednesday, 17 June 2020 at 22:09:35 UTC, mw wrote:

> 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?  :-)

No, I can't.

typedef int* intPtr;
const intPtr ip = new int;
typedef int& intRef;
const intRef i = 3; // oops, does not compile

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

ref int is not a type. What should break is the line

alias intRef = ref int;

should not compile. Looks like it does compile. That's a bug.

> 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:

You're conflating reference types and pass by reference. These are not the same thing in D, and never will be.


June 17, 2020
On Wednesday, 17 June 2020 at 22:33:50 UTC, mw wrote:
> We are talking about pass either `ptr` or `ref` to other functions here.

To quote some more of your previous post:

> 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++

That's the inherent difference here, ref is a half-baked type constructor in C++ (and porting that behaviour to D would be a mistake as it would screw with highly templated code).

But i would agree with you that there is a bug in your initial code, the `ref` should be rejected.
June 17, 2020
On Wednesday, 17 June 2020 at 22:41:21 UTC, mw wrote:

> Here we are discussing how to write:
>
> -- f(pass by value) and
> -- f(pass by ref)
>
> in a simple and straight forward way.

f(T) {}
f(ref T) {}

¯\_(ツ)_/¯
June 17, 2020
On Wednesday, 17 June 2020 at 22:50:01 UTC, Stanislav Blinov wrote:
> On Wednesday, 17 June 2020 at 22:41:21 UTC, mw wrote:
>
>> Here we are discussing how to write:
>>
>> -- f(pass by value) and
>> -- f(pass by ref)
>>
>> in a simple and straight forward way.
>
> f(T) {}
> f(ref T) {}


This alone will not work, have to add more static if's
June 17, 2020
On Wednesday, 17 June 2020 at 22:48:25 UTC, MoonlightSentinel wrote:
> But i would agree with you that there is a bug in your initial

It's not the bug in my code,

> code, the `ref` should be rejected.

it's the compiler's bug not rejecting it, given it's current semantics; instead it *silently* treat alias `ref int` as `int`.
June 17, 2020
On Wednesday, 17 June 2020 at 23:05:59 UTC, mw wrote:
> On Wednesday, 17 June 2020 at 22:48:25 UTC, MoonlightSentinel wrote:
>> But i would agree with you that there is a bug in your initial
>
> It's not the bug in my code,
>
>> code, the `ref` should be rejected.
>
> it's the compiler's bug not rejecting it, given it's current semantics; instead it *silently* treat alias `ref int` as `int`.

It is both. In your code, for trying to use `ref` as a type qualifier when it is not (see [1] for type qualifiers), and in the compiler, for not issuing an error.

[1] https://dlang.org/spec/const3.html
June 17, 2020
On Wednesday, 17 June 2020 at 23:09:55 UTC, Stanislav Blinov wrote:
>> it's the compiler's bug not rejecting it, given it's current semantics; instead it *silently* treat alias `ref int` as `int`.
>
> It is both. In your code, for trying to use `ref` as a type qualifier when it is not (see [1] for type qualifiers), and in

Given the current language semantics, right, it shouldn't be typedef/alias-ed,

But it make the code so complex / ugly to write:

either:

void foo(T)(auto ref T v) if (is(T : int) == __traits(isRef, v)) {}

or

f(    T) /*more static if here*/ { /*potential dup code here*/ }
f(ref T) /*more static if here*/ { /*potential dup code here*/ }

I would call for improvement.


> the compiler, for not issuing an error.
>
> [1] https://dlang.org/spec/const3.html