How to do several enumerations type in Fortran?

Viewed 109

I tried to declare several enumeration types in Fortran.

This funny simple example illustrates well my problem :

program Main
  
  enum, bind(c)
    enumerator :: Colors = 0
    enumerator :: Blue = 1
    enumerator :: Red = 2
    enumerator :: Green = 3
  end enum

  enum, bind(c)
    enumerator :: Size = 0
    enumerator :: Small = 1
    enumerator :: Medium = 2
    enumerator :: Large = 3
  end enum
      
  integer(kind(Colors)) :: myColor

  myColor = Green

  if (myColor == Large) then
    write(*,*) 'MyColor is Large'
  end if

end program Main

I also tried to enclose this enumeration in a type and many others things but none works.

Here I can compare Colors with Size. In C, for example, when I declare color and a size typedef enum, I have no such problem, because the two types are different.

Does it exist a simple solution to have several enumerated type in Fortran?

Otherwise, I imagine to declare several types with one integer member that holds the value and, after, to create interface to overload the operators I need (comparison, affectation and so on). I am not sure that solution is possible and also, I can do it.

1 Answers

Fortran does not have enumerated types in the sense that you wish to use.1

An enumeration in Fortran is a set of enumerators. The program of the question has two of them.

Enumerators themselves are named (integer) constants of a kind interoperable with C's corresponding enumeration type. They exist for the purposes of C interoperability and not to provide a similar functionality within Fortran.

The enumerators Green and Large in the question are two named integer constants with value 3 (of some, possibly different kind). Green==Large is a true expression whatever the kind parameters of the constants.

There is no mechanism in Fortran to restrict a variable to values of an enumeration. The constants could equivalently be declared as

integer(kind=enum_kind1) :: Green = 3_enum_kind1
integer(kind=enum_kind2) :: Large = 3_enum_kind2

for the appropriate kind values (which are quite likely in this case to be the same: C_INT) and the Fortran program would know no difference.

If you wish to use enumerated types in the sense that they exist in C and similar languages, you will have to use a non-intrinsic approach (as intimated in the question).


1 This is the case for the current, 2018, revision of the language. At this time, there is a proposal for the next revision (provisionally 2023) to include enumerated types closer to what is desired here. This specification is given in 7.6.2 of one particular working draft.

Related