March 02, 2018
On Wednesday, 28 February 2018 at 20:07:50 UTC, Steven Schveighoffer wrote:
> auto x = cast(Object)((cast(size_t *)null) + 1);

Is this preferred performance-wise over `cast(void*)(size_t.max)`?
March 02, 2018
On 3/2/18 3:26 PM, Nordlöw wrote:
> On Wednesday, 28 February 2018 at 20:07:50 UTC, Steven Schveighoffer wrote:
>> auto x = cast(Object)((cast(size_t *)null) + 1);
> 
> Is this preferred performance-wise over `cast(void*)(size_t.max)`?

No, it just works, as opposed to, um... not working ;)

I think the compiler senses you are trying to do something foolish (even though that's not the case), and prevents you from doing it. For some reason it doesn't care about it if it starts out as a pointer.

If both worked, or even cast(void *)(size_t.sizeof) worked, then the performance would be the same, as you are casting a constant.

What you are looking for is a sentinel to check against. Either works OK. As I said before, items in the zero page are not going to be mapped by the OS. I'm not sure about size_t.max.

-Steve
March 05, 2018
On Wednesday, 28 February 2018 at 20:07:50 UTC, Steven Schveighoffer wrote:
> auto x = cast(Object)((cast(size_t *)null) + 1);

Thanks, how do I store it as enum or static immutable struct member?

In

@trusted pure unittest
{
    class C { int value; }
    C x;
    C y = cast(C)((cast(size_t*)null) + 1); // indicates a lazily deleted key
    struct S
    {
        enum C hole1 = cast(C)((cast(size_t*)null) + 1); // TODO make work
        static immutable C hole2 = cast(C)((cast(size_t*)null) + 1); // TODO make work
    }
}

both `enum` and static` immutable` member declarations fail to compile with the same errors:

Error: cannot perform pointer arithmetic on non-arrays at compile time
Error: cannot perform pointer arithmetic on non-arrays at compile time

My only possible solution so far is to return the expression from an inline member function which I guess cannot be optimized as good as comparing to a compile-time value.
March 05, 2018
On 3/5/18 6:41 AM, Nordlöw wrote:
> On Wednesday, 28 February 2018 at 20:07:50 UTC, Steven Schveighoffer wrote:
>> auto x = cast(Object)((cast(size_t *)null) + 1);
> 
> Thanks, how do I store it as enum or static immutable struct member?
> 
> In
> 
> @trusted pure unittest
> {
>      class C { int value; }
>      C x;
>      C y = cast(C)((cast(size_t*)null) + 1); // indicates a lazily deleted key
>      struct S
>      {
>          enum C hole1 = cast(C)((cast(size_t*)null) + 1); // TODO make work
>          static immutable C hole2 = cast(C)((cast(size_t*)null) + 1); // TODO make work
>      }
> }
> 
> both `enum` and static` immutable` member declarations fail to compile with the same errors:
> 
> Error: cannot perform pointer arithmetic on non-arrays at compile time
> Error: cannot perform pointer arithmetic on non-arrays at compile time
> 
> My only possible solution so far is to return the expression from an inline member function which I guess cannot be optimized as good as comparing to a compile-time value.

Weird, I would have expected to be able to map addresses at compile time, I suppose the way you could work it is:

pragma(inline, true)
C lazyDeleted() pure nothrow @trusted { return cast(C)((cast(size_t*)null) + 1); }

Then you can simply use this like it was an enum or immutable. It should go away in terms of a function call.

-Steve
March 05, 2018
On Monday, 5 March 2018 at 12:41:06 UTC, Steven Schveighoffer wrote:
> pragma(inline, true)
> C lazyDeleted() pure nothrow @trusted { return cast(C)((cast(size_t*)null) + 1); }

I still can't evaluate at compile-though...

        enum holeKeyOffset = 0x1;

        pragma(inline, true)
        static K holeKey() @trusted pure nothrow @nogc
        {
            return cast(K)((cast(size_t*)null) + holeKeyOffset);
        }

        enum _ = holeKey;

fails as

    Error: cannot perform pointer arithmetic on non-arrays at compile time

March 05, 2018
On 3/5/18 9:01 AM, Nordlöw wrote:
> On Monday, 5 March 2018 at 12:41:06 UTC, Steven Schveighoffer wrote:
>> pragma(inline, true)
>> C lazyDeleted() pure nothrow @trusted { return cast(C)((cast(size_t*)null) + 1); }
> 
> I still can't evaluate at compile-though...
> 
>          enum holeKeyOffset = 0x1;
> 
>          pragma(inline, true)
>          static K holeKey() @trusted pure nothrow @nogc
>          {
>              return cast(K)((cast(size_t*)null) + holeKeyOffset);
>          }
> 
>          enum _ = holeKey;
> 
> fails as
> 
>      Error: cannot perform pointer arithmetic on non-arrays at compile time

No, I mean you call holeKey at *runtime*. Inlined, it's just returning a constant, so it should reduce to a constant.

-Steve
March 05, 2018
On Monday, 5 March 2018 at 16:07:49 UTC, Steven Schveighoffer wrote:
> No, I mean you call holeKey at *runtime*. Inlined, it's just returning a constant, so it should reduce to a constant.

A compile-time constant visible to the optimizer?
March 05, 2018
On Monday, 5 March 2018 at 18:04:20 UTC, Nordlöw wrote:
> On Monday, 5 March 2018 at 16:07:49 UTC, Steven Schveighoffer wrote:
>> No, I mean you call holeKey at *runtime*. Inlined, it's just returning a constant, so it should reduce to a constant.
>
> A compile-time constant visible to the optimizer?

Yes indeed. For gdc and ldc the optimisation is guranteed and I am quite dmd can do this as well. As long as you don't have too many statements.
March 05, 2018
On 3/5/18 1:08 PM, Stefan Koch wrote:
> On Monday, 5 March 2018 at 18:04:20 UTC, Nordlöw wrote:
>> On Monday, 5 March 2018 at 16:07:49 UTC, Steven Schveighoffer wrote:
>>> No, I mean you call holeKey at *runtime*. Inlined, it's just returning a constant, so it should reduce to a constant.
>>
>> A compile-time constant visible to the optimizer?
> 
> Yes indeed. For gdc and ldc the optimisation is guranteed and I am quite dmd can do this as well. As long as you don't have too many statements.

Note, I think the error is bogus, you should be able to create hard-coded addresses of data at compile time -- I'm not sure how you would do hardware registers otherwise.

Another possibility I thought of:

struct Dummy
{
    size_t nullValue;
    void *holeKey;
}

enum holeKey = &(cast(Dummy *)null).holeKey;

But this fails as well

Error: dereference of null pointer null

-Steve
March 06, 2018
On Monday, 5 March 2018 at 18:28:43 UTC, Steven Schveighoffer wrote:
> Note, I think the error is bogus, you should be able to create hard-coded addresses of data at compile time -- I'm not sure how you would do hardware registers otherwise.

I'd do them as extern variables, it wouldn't be nice to have them as pointers.
extern int reg1;
And use linker option to define address: --defsym reg1=0x1111