Is enum static?

H. S. Teoh hsteoh at quickfur.ath.cx
Tue Aug 20 14:16:32 PDT 2013


On Tue, Aug 20, 2013 at 05:01:36PM -0400, Jonathan M Davis wrote:
> On Tuesday, August 20, 2013 13:35:43 H. S. Teoh wrote:
[...]
> > It should be possible to write things like:
> > 
> > byte[] a = [1,2,3,4];
> > 
> > and *not* incur the overhead of allocating an int[] and then copying it
> > over (with implicit casting) to the byte[].
> 
> That doesn't allocate anymore, and there are plenty of cases like that
> (several of which I'm sure still allocate), but it's essentially an
> optimization any time that an array literal doesn't end up allocating.

That's what troubles me. Allocations shouldn't be the default; they
should be fallback when they can't be avoided.


> > On that note, I find it Very Evil that this doesn't work properly:
> > 
> > char[] a = "abc";
> > const(char)[] b = "abc";
> > 
> > Instead, you have to do:
> > 
> > char[] a = "abc".dup;
> > const(char)[] b = "abc".dup;
> >
> > I can accept that having an explicit .dup or .idup is a good thing
> > when the source string is a variable, but in this case, the compiler
> > *should* be smart enough to know, hey, "abc" is a literal and is
> > being immediately assigned to a char[], so the user must intend that
> > it's used only to initialize the char[], so I don't need to actually
> > allocate a *string* (as in, immutable(char)[]) for the literal and
> > copy it, but instead, I should generate code to initialize each
> > array element.
> > 
> > tl;dr, I think D literals are assigned a type far too early in the
> > compilation process. The intended meaning of a literal shouldn't be
> > bound until the compiler is able to infer from context what type is
> > actually required.
> 
> Honestly, I have no problem with this. The type of string literal is
> immutable(char)[], so having to dup it makes sense. And you don't
> incur any extra allocations, because string literals are part of the
> generated binary rather than being allocated at runtime (and on Linux,
> they end up in the read- only portion). So, you're only allocating
> once (when you dup), which is what what happen if the compiler allowed
> the code that you're looking for.
[...]

It's not just with strings. What about this:

	byte[] a = [1,2,3];
	uint[] b = [1,2,3];
	long[] c = [1,2,3];

?  Will the compiler emit an int[] (or immutable(int)[]?) to hold each
literal, and then copy the contents (with casting) to the target arrays
at runtime?

I argue that [1,2,3] has a different meaning in each of these lines. On
the first line, it should mean [byte(1), byte(2), byte(3)], on the
second line it should mean [1u, 2u, 3u], and on the third line it should
mean [1L, 2L, 3L]. The compiler should not assign it to int[] except as
a fallback (e.g., if you wrote auto d = [1,2,3];, then it would default
to int[]).

This issues shows up in places like IFTI, where [1,2,3] is assigned too
early to be int[], so it fails to match a template function that expects
byte[]. IFTI can of course be hacked to work around this (and maybe
already has), but the fundamental problem is that literals are assumed
to be of a particular type far too early on. They really should have
flexible type, adaptable to the context they appear in. A literal like
[1,2,3] should not be be assumed to be int[] until the compiler
determines that the context does not provide sufficient information to
deduce the intended type. IOW, int[] should be a *fallback* type for
[1,2,3], not something presumed up-front.


T

-- 
Which is worse: ignorance or apathy? Who knows? Who cares? -- Erich Schubert


More information about the Digitalmars-d-learn mailing list