Jump to content
A.M. Hoornweg

What is this syntax?

Recommended Posts

Hello all,

 

I recently stumbled upon some code whose syntax was new to me. That doesn't happen too often so I'm slightly overwhelmed.  How do you call this elegant way of declaring constants, and is it documented somewhere? I especially like the implicit association between a type and values.

  

Type tSomeType=(
  begindoc=$01,
  Newpage=$02,
  enddoc=$03
);

 

 

Edited by A.M. Hoornweg

Share this post


Link to post
3 minutes ago, Uwe Raabe said:

Thank you!

 

So if I understand correctly, it's just an enum with explicitly defined integer values instead of the default 0...X sequence that the compiler would otherwise generate. 

 

Too bad, my first impression was that the constants had an implicit associated data type (integer) and that I could use it for stuff like

Type tnumerals=(
one='uno',
two='due')

 

but that clearly isn't the case.  Too bad.

 

But still, I think the syntax is very handy for some of my purposes.

 

Share this post


Link to post
50 minutes ago, A.M. Hoornweg said:

But still, I think the syntax is very handy for some of my purposes.

Explicit ordinal values tends to be used for interop with external libs. It's rarely useful for pure delphi code. 

Share this post


Link to post

Note though that this kind of enums has only limited support in RTTI.

 

btw: This has been available since Delphi 6, so you are rather late to the party. 😉

Share this post


Link to post
1 hour ago, David Heffernan said:

Explicit ordinal values tends to be used for interop with external libs. It's rarely useful for pure delphi code. 

I very often have the case that I need to parse records in files and data streams where some integer field identifies the type of content that follows. Some of them were generated by software of my own, some by others.  So for that, it is eminently useful:  Instead of declaring tons of constants with prefixes to clarify the context they apply to, one just declares an enum which locks the constants into a common namespace.

 

For example, look at what Borland did a long time ago in units System.pas and Variants.pas.   It's full of prefixed constants like VarEmpty, VarNull, VarInteger .... where a single enum

 

type tVariantType=
 (Empty=0,
  Null=1,
  ...)


would have been much prettier.  This example comes to mind because I need to decode and encode variants quite often.  

  • Like 1

Share this post


Link to post
2 hours ago, David Heffernan said:

Explicit ordinal values tends to be used for interop with external libs. It's rarely useful for pure delphi code. 

I used to have enums starting from 1 when I needed 0 value to have "null" meaning so that empty structures would be inited with "null". However, I didn't want that null belong to enum itself. So I did

TEnum = (enOne = 1, enTwo, ...)

enNull = TEnum(0)

However, this is not portable (FPC appears much more strict regarding range checking) and lacks RTTI which I use widely so I changed declarations to

TEnumNullable = (enNull, enOne, enTwo, ...)

TEnum = enOne..High(TEnumNullable)

Edited by Fr0sT.Brutal

Share this post


Link to post

I just tried if succ() and pred() work correctly with eplicit ordinal values if there are gaps between the numbers.  They don't.  Too bad, it would have been totally cool. 

Share this post


Link to post
4 hours ago, A.M. Hoornweg said:

For example, look at what Borland did a long time ago in units System.pas and Variants.pas.

This is interop. 

Share this post


Link to post
Guest
On 8/11/2021 at 10:23 AM, David Heffernan said:

Explicit ordinal values tends to be used for interop with external libs. It's rarely useful for pure delphi code. 

 

type

  myEnum = (meFirst = 0, meSecond, meThird);

...

 

myUnitExternalButCompiledArray[Ord(myEnum)]

 

...

 

Pure Delphi. Useful or "anti-pattern"?

Please note that this is not a flame, it is a sincere question.

 

Regards,

 

/D

Share this post


Link to post
1 hour ago, Dany Marmur said:

Useful or "anti-pattern"?

You tell me. What is the use here? You have not explained the intention. 

Share this post


Link to post
5 hours ago, Dany Marmur said:

type

  myEnum = (meFirst = 0, meSecond, meThird);

Enums always start at 0 implicitly, unless explicitly stated otherwise.

5 hours ago, Dany Marmur said:

Pure Delphi. Useful or "anti-pattern"?

Nothing wrong with using an enum for array indexes, provided the enum elements start at 0 and are sequential, which is the default behavior.

type
  myEnum = (meFirst, meSecond, meThird);

myUnitExternalButCompiledArray[meFirst]
myUnitExternalButCompiledArray[meSecond]
myUnitExternalButCompiledArray[meThird]

var e: myEnum;
e := ...;
myUnitExternalButCompiledArray[Ord(e)]

 

Share this post


Link to post
Guest

So writing "= 0" is similar to "explaining variables" IMHO. Not the worst.

Share this post


Link to post
59 minutes ago, Dany Marmur said:

So writing "= 0" is similar to "explaining variables" IMHO. Not the worst.

Actually, it might cause an enum to not have RTTI:

 

"Enumerated constants with a specific value [...] do not have RTTI.

(from http://docwiki.embarcadero.com/RADStudio/Sydney/en/Simple_Types_(Delphi)#Enumerated_Types_with_Explicitly_Assigned_Ordinality )

 

(I didn't check this.)

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×