www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - manifest enum

reply John Reimer <terminal.node gmail.com> writes:
This may have been asked before, but the documentation isn't clear:

With the new enum in D 2.0, is there a difference between a singly 
declared manifest:

enum i=4;

and the anonymous enum block:

enum {
     A = 1.2f,
     B = 2L,
     C = 3
}

The docs say that the singly declared manifest enum is not an lvalue and 
it's address can be taken (which is eaasy to understand).  However, does 
this apply to the anonymous enum in the second case also?

Put another way, does the second case classify as a /list/ of manifest 
enums?

If the two are not the same... then a I guess a manifest enum has to be 
declared every line with "enum" in front which would become rather 
painfully redundant given that other structures in the language allow 
you to group several declarations in a block (extern).

On the other hand if an anonymous enum block /is/ the same as a single 
manifest constant, then it becomes confusing and hard to differentiate 
the old enum type in a listing from the manifest enums.  Maybe this was 
one of the arguments against it in earlier discussions?

I can settle for the name "enum", but it does seem to add a unusual 
level of confusion.  Granted I'm probably bringing up something that's 
been hashed over in previous discussions already.

-JJR
Jan 01 2008
next sibling parent John Reimer <terminal.node gmail.com> writes:
John Reimer wrote:
 This may have been asked before, but the documentation isn't clear:
 
 With the new enum in D 2.0, is there a difference between a singly 
 declared manifest:
 
 enum i=4;
 
 and the anonymous enum block:
 
 enum {
     A = 1.2f,
     B = 2L,
     C = 3
 }
 
 The docs say that the singly declared manifest enum is not an lvalue and 
 it's address can be taken (which is eaasy to understand).

correction: "...and it's address /can't/ be taken (which is easy to understand)." Argh! -JJR
Jan 01 2008
prev sibling next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Tue, 01 Jan 2008 12:02:04 -0800, John Reimer wrote:

 This may have been asked before, but the documentation isn't clear:
 
 With the new enum in D 2.0, is there a difference between a singly 
 declared manifest:
 
 enum i=4;
 
 and the anonymous enum block:
 
 enum {
      A = 1.2f,
      B = 2L,
      C = 3
 }
 
 The docs say that the singly declared manifest enum is not an lvalue and 
 it's address can be taken (which is eaasy to understand).  However, does 
 this apply to the anonymous enum in the second case also?
 
 Put another way, does the second case classify as a /list/ of manifest 
 enums?
 
 If the two are not the same... then a I guess a manifest enum has to be 
 declared every line with "enum" in front which would become rather 
 painfully redundant given that other structures in the language allow 
 you to group several declarations in a block (extern).
 
 On the other hand if an anonymous enum block /is/ the same as a single 
 manifest constant, then it becomes confusing and hard to differentiate 
 the old enum type in a listing from the manifest enums.  Maybe this was 
 one of the arguments against it in earlier discussions?
 
 I can settle for the name "enum", but it does seem to add a unusual 
 level of confusion.  Granted I'm probably bringing up something that's 
 been hashed over in previous discussions already.
 
 -JJR

There is no difference between a group of manifest constants and a single manifest constant. enum x = 3; enum y = "four"; and enum {x = 3, y = "four"}; are semantically identical. The documenation says this ... "If there is only one member of an anonymous enum, the { } can be omitted". -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jan 01 2008
parent reply John Reimer <terminal.node gmail.com> writes:
YDerek Parnell wrote:

 
 There is no difference between a group of manifest constants and a single
 manifest constant.
 
   enum x = 3;
   enum y = "four";
 
 and
 
   enum {x = 3, y = "four"};
 
 are semantically identical.
 
 The documenation says this ...
 
 "If there is only one member of an anonymous enum, the { } can be omitted".
 

Yep, I read that. But it wasn't clear to me that the following statement applied to anonymous enums also: "such declarations are not lvalues, meaning their address cannot be taken." The fact that both these statements were in a separate section titled "Manifest Constants" made it look like these were treated as an independent entity from "Anonymous Enums", the section just before it. Perhaps I should have inferred that the prhase "the { } can be omitted" indicated they were one and the same, but I still think it's somewhat unclearly documented. If anonymous enums and manifest constants are the same, then the section "Manifest Constants" should probably be removed and the sections merged. A reference can be made to the fact that these represent two different forms of manifest constants. Then the statement on lvalue would be taken to refer to both forms. -JJR
Jan 01 2008
parent reply Sean Kelly <sean f4.ca> writes:
John Reimer wrote:
 YDerek Parnell wrote:
 
 There is no difference between a group of manifest constants and a single
 manifest constant.

   enum x = 3;
   enum y = "four";

 and

   enum {x = 3, y = "four"};

 are semantically identical.

 The documenation says this ...

 "If there is only one member of an anonymous enum, the { } can be 
 omitted".

Yep, I read that. But it wasn't clear to me that the following statement applied to anonymous enums also: "such declarations are not lvalues, meaning their address cannot be taken." The fact that both these statements were in a separate section titled "Manifest Constants" made it look like these were treated as an independent entity from "Anonymous Enums", the section just before it.

'enum' is now basically a storage class in addition to an enumeration specifier, so you can even do this I believe: enum: a = 1; b = 2; Sean
Jan 01 2008
next sibling parent reply John Reimer <terminal.node gmail.com> writes:
Sean Kelly wrote:

 'enum' is now basically a storage class in addition to an enumeration 
 specifier, so you can even do this I believe:
 
 enum:
     a = 1;
     b = 2;
 
 
 Sean

I'll have to test it out and see (that must have been based on earlier discussions?). But doing that would seem strange... and maybe a little ambiguous? What marks the end of the "enum:" specifier sequence for manifest constants then?
Jan 01 2008
parent Sean Kelly <sean f4.ca> writes:
John Reimer wrote:
 Sean Kelly wrote:
 
 'enum' is now basically a storage class in addition to an enumeration 
 specifier, so you can even do this I believe:

 enum:
     a = 1;
     b = 2;


 Sean

I'll have to test it out and see (that must have been based on earlier discussions?). But doing that would seem strange... and maybe a little ambiguous? What marks the end of the "enum:" specifier sequence for manifest constants then?

The end of the scope I think. And I should qualify this by saying I haven't tried it, but it would be consistent with what Walter has said in the past. So far, the only slightly tricky thing I've found is where the new behavior overlaps the old behavior: enum { a = byte.max } In D 1.0, the type of 'a' is int, and in D 2.0 the type is 'byte', because the type in D 2.0 is inferred from the initializer. So for portability, such declarations should always be specified with a type qualifier: enum : int { a = byte.max } Fortunately, implicit narrowing conversions seem to be disallowed in D 1.0 here, so this is illegal and thus not a portability problem: enum { a = long.max } It's legal in D 2.0 however, and the resulting type is 'long', as you'd expect. Sean
Jan 01 2008
prev sibling parent reply Walter Bright <newshound1 digitalmars.com> writes:
Sean Kelly wrote:
 'enum' is now basically a storage class in addition to an enumeration 
 specifier, so you can even do this I believe:
 
 enum:
     a = 1;
     b = 2;

No, it's not a storage class and that won't work.
Jan 01 2008
parent Sean Kelly <sean f4.ca> writes:
Walter Bright wrote:
 Sean Kelly wrote:
 'enum' is now basically a storage class in addition to an enumeration 
 specifier, so you can even do this I believe:

 enum:
     a = 1;
     b = 2;

No, it's not a storage class and that won't work.

Oops, my mistake. Sean
Jan 03 2008
prev sibling next sibling parent reply John Reimer <terminal.node gmail.com> writes:
John Reimer wrote:

 On the other hand if an anonymous enum block /is/ the same as a single 
 manifest constant, then it becomes confusing and hard to differentiate 
 the old enum type in a listing from the manifest enums.  Maybe this was 
 one of the arguments against it in earlier discussions?
 
 I can settle for the name "enum", but it does seem to add a unusual 
 level of confusion.  Granted I'm probably bringing up something that's 
 been hashed over in previous discussions already.
 
 -JJR
 
 

Okay, I was jumping the gun. It seems anonymous enums are synonymous with manifest constants, period -- singly or block declared. I can live with that. I suppose there shouldn't be any confusion. Although, I think the docs could clearer as indicated in my last post. -JJR
Jan 01 2008
parent Derek Parnell <derek psych.ward> writes:
On Tue, 01 Jan 2008 14:37:11 -0800, John Reimer wrote:

 
 Although, I think the docs could clearer as indicated in my last post.

I don't think anyone has accused D of being too well documented ;-) But there is only one Walter and everything, including documentation improvements, must go through him as the final process step. -- Derek Parnell Melbourne, Australia skype: derek.j.parnell
Jan 01 2008
prev sibling parent reply Russell Lewis <webmaster villagersonline.com> writes:
Have a look at this code:

   enum Named {
     uint foo = 1;
          bar = 2;
   };
   enum /* anonymous */ {
     uint fred  = 1;
          wilma = 2;
   };



In the above, unless I'm mistaken, typeof(bar) is uint, but 
typeof(wilma) is int.  Right?  So just naming a previously unnamed enum 
changes the types of the elements?

Ick.
Jan 02 2008
parent reply "Janice Caron" <caron800 googlemail.com> writes:
On 1/2/08, Russell Lewis <webmaster villagersonline.com> wrote:
 Have a look at this code:

    enum Named {
      uint foo = 1;
           bar = 2;
    };

I don't think that will compile. The whole point of naming an enum is to create a new type, so that you can subsequently declare: Named x;
Jan 02 2008
parent Russell Lewis <webmaster villagersonline.com> writes:
Janice Caron wrote:
 On 1/2/08, Russell Lewis <webmaster villagersonline.com> wrote:
 Have a look at this code:

    enum Named {
      uint foo = 1;
           bar = 2;
    };

I don't think that will compile. The whole point of naming an enum is to create a new type, so that you can subsequently declare: Named x;

Sorry, right. So this: enum Named { foo = 1U; bar = 2; };
Jan 02 2008