www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [dox] enum specs vs reality

reply captaindet <2krnk gmx.net> writes:
i admit that i am not very good at reading/understanding language definition
syntax. but yet i think the given enum specs ( http://dlang.org/enum.html ) are
not quite in order.

they seem to imply that both

enum ;
enum WhatAmI ;

are correct. while the first one throws an error as expected, the second one
passes and is partially usable, potentially similar to C's #define OPTION.
however, typedef's throwing of an error makes me doubt that this is legal:

----
import std.stdio, std.traits;

enum test;		// passes but is it really legal?

int main(string[] args)
{
	writeln( __traits(compiles, test) );	// true

	writeln( is( test == enum ) );			// true
	
	writeln( isBasicType!(test) );			// true

	writeln( isSomeFunction!(test) );		// false

	//  writeln( typeof(test).stringof );		// Error: argument test to typeof is
not an expression

	return 0;
}
Aug 27 2013
next sibling parent reply "Andre Artus" <andre.artus gmail.com> writes:
On Tuesday, 27 August 2013 at 23:52:59 UTC, captaindet wrote:
 i admit that i am not very good at reading/understanding 
 language definition syntax. but yet i think the given enum 
 specs ( http://dlang.org/enum.html ) are not quite in order.

 they seem to imply that both

 enum ;
 enum WhatAmI ;

You are right. Given the rules marked with asterisks below your examples would be legal. EnumDeclaration: * enum EnumTag EnumBody * enum EnumBody enum EnumTag : EnumBaseType EnumBody enum : EnumBaseType EnumBody EnumBody: * EmptyEnumBody EnumMembersBody EmptyEnumBody: * ; Going by the description on the linked page EmptyEnumBody should probably be something like this: EmptyEnumBody: EnumMember ; Although going by examples [2] from Andrei's book ("The D Programming Language"), it seems the following is valid: EmptyEnumBody: EnumMembers ; 2. The example from p.69 [TDPL]. It seems to be missing a colon after "enum". enum size_t g_maxDataSize = 100_000_000, g_maxMemory = 1_000_000_000; I hope someone can clear up what is and isn't a valid enum.
Aug 27 2013
parent reply Jacob Carlborg <doob me.com> writes:
On 2013-08-28 04:27, Andre Artus wrote:

 2. The example from p.69 [TDPL]. It seems to be missing a colon after
 "enum".
 enum size_t g_maxDataSize = 100_000_000, g_maxMemory = 1_000_000_000;

 I hope someone can clear up what is and isn't a valid enum.

I haven't looked at this in TPL but the above is a manifest constant. Which basically has nothing to do with enums. It's a way to declare a constant that doesn't have any storage and which address cannot be taken. Basically the same as "#define foo 0" in C. -- /Jacob Carlborg
Aug 28 2013
parent reply captaindet <2krnk gmx.net> writes:
On 2013-08-28 02:21, Jacob Carlborg wrote:
 On 2013-08-28 04:27, Andre Artus wrote:

 2. The example from p.69 [TDPL]. It seems to be missing a colon
 after "enum". enum size_t g_maxDataSize = 100_000_000, g_maxMemory
 = 1_000_000_000;

 I hope someone can clear up what is and isn't a valid enum.

I haven't looked at this in TPL but the above is a manifest constant. Which basically has nothing to do with enums. It's a way to declare a constant that doesn't have any storage and which address cannot be taken. Basically the same as "#define foo 0" in C.

don't know what you mean. since they are defined with the enum keyword they have everything to do with enum, especially the official syntax presented here: http://dlang.org/enum.html enum keyword covers both, enumeration constants and manifest constants. the specs cover both in one. moreover, they explain that manifest constants are only syntactic sugar for anonymous enums: enum { A = 2, B = 4 } is the same as enum A = 2; enum B = 4;
Aug 28 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-08-28 17:26, captaindet wrote:

 enum keyword covers both, enumeration constants and manifest constants.
 the specs cover both in one. moreover, they explain that manifest
 constants are only syntactic sugar for anonymous enums:

 enum { A = 2, B = 4 }

 is the same as

 enum A = 2;
 enum B = 4;

The above is short for: enum int A = 2; enum int B = 4; They declare manifest constants, not types. It's the same as: immutable int A = 2; But you can't take the address of "A", which you can if it's declared as immutable. -- /Jacob Carlborg
Aug 28 2013
prev sibling next sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2013-08-28 01:53, captaindet wrote:
 i admit that i am not very good at reading/understanding language
 definition syntax. but yet i think the given enum specs (
 http://dlang.org/enum.html ) are not quite in order.

 they seem to imply that both

 enum ;
 enum WhatAmI ;

That doesn't look entirely correct. Currently the docs read: EnumDeclaration: enum EnumBody Should probably be: EnumDeclaration: enum EnumMembersBody:
 are correct. while the first one throws an error as expected, the second
 one passes and is partially usable, potentially similar to C's #define
 OPTION. however, typedef's throwing of an error makes me doubt that this
 is legal:

 ----
 import std.stdio, std.traits;

 enum test;        // passes but is it really legal?

 int main(string[] args)
 {
      writeln( __traits(compiles, test) );    // true

      writeln( is( test == enum ) );            // true

      writeln( isBasicType!(test) );            // true

      writeln( isSomeFunction!(test) );        // false

      //  writeln( typeof(test).stringof );        // Error: argument
 test to typeof is not an expression

      return 0;
 }

The last one will fail since "typeof" expects an expression and not a type. -- /Jacob Carlborg
Aug 28 2013
next sibling parent reply captaindet <2krnk gmx.net> writes:
On 2013-08-28 02:26, Jacob Carlborg wrote:
 That doesn't look entirely correct. Currently the docs read:

 EnumDeclaration:
 enum EnumBody

 Should probably be:

 EnumDeclaration:
 enum EnumMembersBody:

agreed.
 The last one will fail since "typeof" expects an expression and not a type.

a) so are you saying enum WhatAmI; is legal? (just asking because i don't know) b) what typeof expects/tolerates seems to be a bit of a minefield by itself. enum test = true; writeln( typeof(test).stringof ); //prints: bool enum wtf; writeln( typeof(wtf).stringof ); //Error: argument wtf to typeof is not an expression /det
Aug 28 2013
next sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-08-28 17:34, captaindet wrote:

 The last one will fail since "typeof" expects an expression and not a
 type.

a) so are you saying enum WhatAmI; is legal? (just asking because i don't know)

Yes, it's sometimes usable to be able to declare dummy types like this. Especially now when we have UAD's (User Defined Attribute): enum foo; foo bar ();
 b) what typeof expects/tolerates seems to be a bit of a minefield by
 itself.

 enum test = true;
 writeln( typeof(test).stringof );    //prints: bool

 enum wtf;
 writeln( typeof(wtf).stringof );    //Error: argument wtf to typeof is
 not an expression

That seems strange. Perhaps worth a bugzilla report: http://d.puremagic.com/issues/ -- /Jacob Carlborg
Aug 28 2013
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2013-08-28 17:34, captaindet wrote:

 b) what typeof expects/tolerates seems to be a bit of a minefield by
 itself.

 enum test = true;
 writeln( typeof(test).stringof );    //prints: bool

 enum wtf;
 writeln( typeof(wtf).stringof );    //Error: argument wtf to typeof is
 not an expression

Actually, I previously misread this. This is working as it should. The first declares a manifest constant: enum test = true Is short for: enum bool test = ture; "bool" is the type, "test" is the name. The second declares a new type, where "wtf" is the name of the type. -- /Jacob Carlborg
Aug 28 2013
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 8/28/13, Jacob Carlborg <doob me.com> wrote:
 Yes, it's sometimes usable to be able to declare dummy types like this.
 Especially now when we have UAD's (User Defined Attribute):

 enum foo;

  foo bar ();

Good tip, I used to use structs for this but I wanted something non-instantiable.
Aug 28 2013
prev sibling parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Aug 28, 2013 at 09:12:44PM +0200, Andrej Mitrovic wrote:
 On 8/28/13, Jacob Carlborg <doob me.com> wrote:
 Yes, it's sometimes usable to be able to declare dummy types like
 this.  Especially now when we have UAD's (User Defined Attribute):

 enum foo;

  foo bar ();

Good tip, I used to use structs for this but I wanted something non-instantiable.

Good idea! I also don't like using structs everywhere just for UDA's. T -- MSDOS = MicroSoft's Denial Of Service
Aug 28 2013
prev sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Tuesday, 27 August 2013 at 23:52:59 UTC, captaindet wrote:
 enum WhatAmI ;

I suppose this is legal for the same reasons as class A; or struct S; is legal - forward declaration (although in case of enums it is pretty useless).
Aug 28 2013
parent Jacob Carlborg <doob me.com> writes:
On 2013-08-28 19:31, Maxim Fomin wrote:

 I suppose this is legal for the same reasons as class A; or struct S; is
 legal - forward declaration (although in case of enums it is pretty
 useless).

It's useful for UDA's: enum foo; foo bar (); -- /Jacob Carlborg
Aug 28 2013