March 02, 2018 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nordlöw | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Stefan Koch | 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 Re: Validity of cast(void*)size_t.max | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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
|
Copyright © 1999-2021 by the D Language Foundation