Jump to page: 1 2 3
Thread overview
What is the difference between enum and shared immutable?
Oct 28, 2020
Jan Hönig
Oct 28, 2020
H. S. Teoh
Oct 29, 2020
matheus
Oct 29, 2020
Mike Parker
Oct 29, 2020
matheus
Oct 29, 2020
Ali Çehreli
Oct 29, 2020
Imperatorn
Oct 29, 2020
Jan Hönig
Oct 29, 2020
IGotD-
Oct 29, 2020
H. S. Teoh
Oct 29, 2020
Ali Çehreli
Oct 29, 2020
IGotD-
Oct 29, 2020
H. S. Teoh
Oct 29, 2020
Ali Çehreli
Oct 30, 2020
Max Samukha
Oct 28, 2020
IGotD-
Oct 29, 2020
H. S. Teoh
Oct 29, 2020
H. S. Teoh
Oct 30, 2020
Daniel Kozak
October 28, 2020
Maybe this is a silly question, but I don't understand completely the difference between an `enum` and a `shared immutable`.

I could have:

enum x = 1;

or

shared immutable x = 1;

What is the exact difference between those too?

My best guess is, that shared immutable gets initialized during the beginning of the programm execution.
Enum has to be "ready" at compile time.
Is this this accessment correct and complete?
Am I missing anything else?

(If correct, then I understand that shared immutable is capable of doing some sideeffects during is construction (if the constructor does that))
October 28, 2020
On Wed, Oct 28, 2020 at 09:54:19PM +0000, Jan Hönig via Digitalmars-d-learn wrote:
> Maybe this is a silly question, but I don't understand completely the difference between an `enum` and a `shared immutable`.
> 
> I could have:
> 
> enum x = 1;
> 
> or
> 
> shared immutable x = 1;
> 
> What is the exact difference between those too?
[...]

An enum only exists at compile-time, and does not occupy any space. Each time it's referenced, a new instance of the value is created.  (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)

A shared immutable is initialized at compile-time, and occupies space in the object file / runtime memory. It's also a single instance, and referencing it causes a load of this instance at runtime.  It's not copied unless it's a by-value type, so an array literal will get stored as an array in the executable, and every time you reference it you get a slice of it instead of a copy.


T

-- 
In order to understand recursion you must first understand recursion.
October 28, 2020
On Wednesday, 28 October 2020 at 21:54:19 UTC, Jan Hönig wrote:
>
> shared immutable x = 1;
>

Is there a point to add shared to an immutable? Aren't immutable implicitly also shared?
October 29, 2020
On Wednesday, 28 October 2020 at 22:07:06 UTC, H. S. Teoh wrote:
> ... (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)
> ...

Could you please give an example (Snippet) about this?

Matheus.
October 29, 2020
On Thursday, 29 October 2020 at 00:55:29 UTC, matheus wrote:
> On Wednesday, 28 October 2020 at 22:07:06 UTC, H. S. Teoh wrote:
>> ... (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)
>> ...
>
> Could you please give an example (Snippet) about this?
>

enum int[] arr = [1,2,3];
someFunc(arr);

This is identical to

someFunc([1,2,3]);

Manifest constants have no address. They are effectively aliases for their values.


October 29, 2020
On Thursday, 29 October 2020 at 01:26:38 UTC, Mike Parker wrote:
>
> enum int[] arr = [1,2,3];
> someFunc(arr);
>
> This is identical to
>
> someFunc([1,2,3]);
>
> Manifest constants have no address. They are effectively aliases for their values.

Hi Mike,

I really didn't know about this.

Thanks for the information,

Matheus.
October 29, 2020
On Wednesday, 28 October 2020 at 22:07:06 UTC, H. S. Teoh wrote:
> [...]
>
> An enum only exists at compile-time, and does not occupy any space. Each time it's referenced, a new instance of the value is created.  (This is why it's a bad idea to use enum with an array literal, because every time it's referenced you get a new copy of the array.)
>
> A shared immutable is initialized at compile-time, and occupies space in the object file / runtime memory. It's also a single instance, and referencing it causes a load of this instance at runtime.  It's not copied unless it's a by-value type, so an array literal will get stored as an array in the executable, and every time you reference it you get a slice of it instead of a copy.
>
>
> T

(thanks to you and Mike btw :)

Is there some rule of thumb when to use what?
I judge that using enum will slow down the compilation process, but might increase performance. So for a small struct, or array enum is completelty fine.
Large arrays should then use immutable, let's say when they are larger than 1kb?

Regarding the shared keyword, I am not sure if immutables are shared per default. I thought they are not.
October 29, 2020
On Thursday, 29 October 2020 at 08:13:42 UTC, Jan Hönig wrote:
> Regarding the shared keyword, I am not sure if immutables are shared per default. I thought they are not.

You can test this with is(TYPE1==TYPE2)

is(shared(immutable(int))==immutable(int))

October 29, 2020
On Thursday, 29 October 2020 at 12:21:19 UTC, Ola Fosheim Grøstad wrote:
>
> You can test this with is(TYPE1==TYPE2)
>
> is(shared(immutable(int))==immutable(int))

So I got that to true, which means that shared immutable is exactly the same as immutable. Shared is implicit for immutable which makes sense.

That means that the documentation
https://dlang.org/articles/migrate-to-shared.html#immutable

is correct at least this one time.
October 29, 2020
On Thu, Oct 29, 2020 at 08:13:42AM +0000, Jan Hönig via Digitalmars-d-learn wrote: [...]
> Is there some rule of thumb when to use what?
>
> I judge that using enum will slow down the compilation process, but might increase performance.

Nah. The slowdown is practically indiscernible. You should be more concerned about the semantics.


> So for a small struct, or array enum is completelty fine.

Actually, I'd recommend *never* to use enum with an array literal, because it comes with a GC allocation *every single time it's referenced*:

	enum E = [ 1 ]; // small array
	...
	auto arr = E; // GC allocation
	if (arr == E) { // another GC allocation
		return E; // yet another GC allocation
	}

Array constants should almost always use static immutable. That way, they get allocated once in the executable, and every reference takes a slice of them instead of incurring a GC allocation every single time.


> Large arrays should then use immutable, let's say when they are larger than 1kb?
[...]

I'd say array constants should *always* use immutable.

Use enum for by-value types like PODs and small structs -- because they can be created in situ without incurring a GC allocation. Depending on the architecture and size of the type, it might even compile into instructions that create the value in CPU registers directly, without allocating stack space for it. So that's something desirable for PODs and small structs.


T

-- 
Why do conspiracy theories always come from the same people??
« First   ‹ Prev
1 2 3