Jump to page: 1 2
Thread overview
Manifest constant class instances
Nov 04, 2018
lngns
Nov 04, 2018
kinke
Nov 04, 2018
lngns
Nov 04, 2018
Alex
Nov 04, 2018
lngns
Nov 04, 2018
kinke
Nov 04, 2018
lngns
Nov 04, 2018
kinke
Nov 04, 2018
kinke
Nov 04, 2018
Alex
Nov 04, 2018
Alex
Nov 04, 2018
lngns
Nov 04, 2018
Alex
Nov 04, 2018
lngns
November 04, 2018
Trying to store a class instance in an enum yields `Unable to initialize enum with class or pointer to struct. Use static const variable instead.`

Given the compiler can access static constants at compile-time too, what are the reasons for not allowing `enum E = new T;`?
I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
November 04, 2018
On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.

A class reference is a pointer too, so using it at runtime would be invalid too.
November 04, 2018
On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>
> A class reference is a pointer too, so using it at runtime would be invalid too.

Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
Am I wrong?
November 04, 2018
On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>
>> A class reference is a pointer too, so using it at runtime would be invalid too.
>
> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
> Am I wrong?

The difference is, that a manifest constant does not possess an address, while a static const does, see e.g.,
https://p0nce.github.io/d-idioms/#Precomputed-tables-at-compile-time-through-CTFE

And if you new an instance, then, you get a pointer, which collides with the way of working of an enum, which is meant to be addressless.
November 04, 2018
On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>
>> A class reference is a pointer too, so using it at runtime would be invalid too.
>
> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
> Am I wrong?

The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.
November 04, 2018
On Sunday, 4 November 2018 at 20:26:13 UTC, Alex wrote:
> On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
>> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>>
>>> A class reference is a pointer too, so using it at runtime would be invalid too.
>>
>> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
>> Am I wrong?
>
> The difference is, that a manifest constant does not possess an address, while a static const does, see e.g.,
> https://p0nce.github.io/d-idioms/#Precomputed-tables-at-compile-time-through-CTFE
>
> And if you new an instance, then, you get a pointer, which collides with the way of working of an enum, which is meant to be addressless.

I do not see how it collides.
This compiles fine:

static const int i = 42;
enum const(int)* ip = &i;

void main()
{
    import std.stdio;
    writeln(*ip); //42
}

An enum can be a pointer.
Plus, given the compiler already applies magic with static const classes by making both the pointer and the actual object static and constant, instead of only the pointer, it looks to me this is a pure implementation detail.
November 04, 2018
On Sunday, 4 November 2018 at 20:50:45 UTC, kinke wrote:
> On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
>> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>>
>>> A class reference is a pointer too, so using it at runtime would be invalid too.
>>
>> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
>> Am I wrong?
>
> The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.

Yes this was actually my point.
Both the compiler and the program refer to the same object, so the pointer is necessarily valid at runtime.
November 04, 2018
On Sunday, 4 November 2018 at 20:57:26 UTC, lngns wrote:
> On Sunday, 4 November 2018 at 20:50:45 UTC, kinke wrote:
>> On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
>>> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>>>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>>>
>>>> A class reference is a pointer too, so using it at runtime would be invalid too.
>>>
>>> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
>>> Am I wrong?
>>
>> The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.
>
> Yes this was actually my point.
> Both the compiler and the program refer to the same object, so the pointer is necessarily valid at runtime.

`enum c = new C()` doesn't imply that the instance lives at runtime too. `static const c = new C()` on the other hand does. This should arguably work though, but doesn't:

```
class C {}
static immutable c = new C();
enum p = c;

void main()
{
    import std.stdio;
    writeln(p);
}
```
November 04, 2018
On Sunday, 4 November 2018 at 21:08:56 UTC, kinke wrote:
> `enum c = new C()` doesn't imply that the instance lives at runtime too.

To make this point clearer: this works, but the instance doesn't live at runtime:

```
class C { int foo() { return 123; } }
enum i = new C().foo();

void main()
{
    import core.stdc.stdio;
    printf("%d\n", i); // i is a 123 literal
}
```
November 04, 2018
On Sunday, 4 November 2018 at 21:08:56 UTC, kinke wrote:
> On Sunday, 4 November 2018 at 20:57:26 UTC, lngns wrote:
>> On Sunday, 4 November 2018 at 20:50:45 UTC, kinke wrote:
>>> On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote:
>>>> On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:
>>>>> On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote:
>>>>>> I can understand for pointers to struct, as the pointer will be invalid at runtime, but, unless I am mistaken, classes are not concerned by pointer semantics.
>>>>>
>>>>> A class reference is a pointer too, so using it at runtime would be invalid too.
>>>>
>>>> Yes but given it works with static constants I would assume the compiler already abstracts away this point. Otherwise there would be a mismatch between what the compiler allocates and what the runtime allocates.
>>>> Am I wrong?
>>>
>>> The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.
>>
>> Yes this was actually my point.
>> Both the compiler and the program refer to the same object, so the pointer is necessarily valid at runtime.
>
> `enum c = new C()` doesn't imply that the instance lives at runtime too. `static const c = new C()` on the other hand does. This should arguably work though, but doesn't:
>
> ```
> class C {}
> static immutable c = new C();
> enum p = c;
>
> void main()
> {
>     import std.stdio;
>     writeln(p);
> }
> ```

I think one could argue that `static const c = new C();` does not make the object visible to the compiler and the CTFE engine, but merely the pointer. Yet, it does.
It looks to me the case we are discussing arises from the class reference semantics.
Adding that manifest constants are immutable, I think whether `enum c = new C();` implies the instance lives at runtime or not is an optimization and not a language feature. (unless there are non-aliasing guarantees for const objects?)

That is why I think such code should be valid.
« First   ‹ Prev
1 2