digitalmars.D - Manifest constant class instances
- lngns (8/8) Nov 04 2018 Trying to store a class instance in an enum yields `Unable to
- kinke (3/6) Nov 04 2018 A class reference is a pointer too, so using it at runtime would
- lngns (6/12) Nov 04 2018 Yes but given it works with static constants I would assume the
- Alex (7/20) Nov 04 2018 The difference is, that a manifest constant does not possess an
- lngns (15/36) Nov 04 2018 I do not see how it collides.
- kinke (3/16) Nov 04 2018 The instance for a static class reference lives in the data
- lngns (4/21) Nov 04 2018 Yes this was actually my point.
- kinke (14/36) Nov 04 2018 `enum c = new C()` doesn't imply that the instance lives at
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.
Nov 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.
Nov 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: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?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.
Nov 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: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.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 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: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.On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote: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.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 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:The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 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: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.On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 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:`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); } ```On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote: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.On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 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 } ```
Nov 04 2018
On Sunday, 4 November 2018 at 21:26:23 UTC, kinke wrote:On Sunday, 4 November 2018 at 21:08:56 UTC, kinke wrote:This is kind of interesting... ´´´ import std.stdio; class C { int member; int foo() { member++; return 123 + member; } } enum i = new C().foo(); enum u = &(new C().foo); void main() { import core.stdc.stdio; printf("%d\n", i); // 124 writeln(u()); // 124 writeln(i); // 124 writeln(u()); // 125 } ´´´`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 } ```
Nov 04 2018
On Sunday, 4 November 2018 at 22:06:28 UTC, Alex wrote:Or even better: ´´´ class C { int member; int foo() { member++; return 123 + member; } } enum i = u(); enum u = &(new C().foo); void main() { import std.stdio : writeln; writeln(i); // 124 writeln(u()); // 125 writeln(i); // 124 writeln(u()); // 126 } ´´´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 } ```
Nov 04 2018
On Sunday, 4 November 2018 at 22:23:18 UTC, Alex wrote:On Sunday, 4 November 2018 at 22:06:28 UTC, Alex wrote:So enum-delegates are stored in mutable memory at runtime? Now this looks like a bug.Or even better: ´´´ class C { int member; int foo() { member++; return 123 + member; } } enum i = u(); enum u = &(new C().foo); void main() { import std.stdio : writeln; writeln(i); // 124 writeln(u()); // 125 writeln(i); // 124 writeln(u()); // 126 } ´´´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 } ```
Nov 04 2018
On Sunday, 4 November 2018 at 22:31:48 UTC, lngns wrote:So enum-delegates are stored in mutable memory at runtime? Now this looks like a bug.Just followed the idea of pointer in the enum... Didn't think this is possible ;)
Nov 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: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.On Sunday, 4 November 2018 at 20:50:45 UTC, kinke wrote:`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); } ```On Sunday, 4 November 2018 at 19:28:14 UTC, lngns wrote: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.On Sunday, 4 November 2018 at 19:20:53 UTC, kinke wrote:The instance for a static class reference lives in the data segment of the binary and is not GC-allocated.On Sunday, 4 November 2018 at 19:02:33 UTC, lngns wrote: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?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.
Nov 04 2018