Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Named constants as components of a derived data type

It seems Fortran 90 does not allow named constants in derived data types. Is this true? The following code does not work.

program my_prog
implicit none
   type :: my_type
      integer, parameter :: a = 1
      real(kind(1.d0))   :: b
   end type my_type
   type (my_type) :: complex_type
end program my_prog

The compiler says parameter statement is not permitted in derived type definitions.

When I remove the parameter keyword everything works fine. But then how can I make sure that the component a is not modified elsewhere?

like image 647
user1318806 Avatar asked Oct 06 '13 22:10

user1318806


People also ask

What is derived types?

A derived type is formed by using one or more basic types in combination. Using derived types, an infinite variety of new types can be formed. The array and structure types are collectively called the aggregate types. Note that the aggregate types do not include union types, but a union may contain an aggregate member.

What is a derived type Fortran?

As discussed previously in Variables, there are five built-in data types in Fortran. A derived type is a special form of data type that can encapsulate other built-in types as well as other derived types. It could be considered equivalent to struct in the C and C++ programming languages.


2 Answers

Make the constant (the parameter) a local entity of the main program rather than the type. If you want more control over the visibility and scope of the identifier for the constant, then put the constant in a module.

like image 190
IanH Avatar answered Oct 23 '22 15:10

IanH


According to the Standard, it is not allowed. The component attribute specifier may only be pointer, and dimension for Fortran 90/95 (section 4.4.1), additionally allocatable in Fortran 2003 (Section 4.5.3), and additionally codimension, and contiguousfor Fortran 2008 (section 4.5.4.1).

You can get the documents here.

I ran into a similar problem with the target specifier, that is also not allowed.

EDIT: Why not try private components?

module typedef
  type :: my_type
    integer, private :: a_int = 1
    real(kind(1.d0)) :: b
  contains
    procedure :: a
  end type my_type

contains
  function a(complex_type)
    class(my_type),intent(in) :: complex_type
    integer :: a
    a = complex_type%a_int
  end function
end module

program my_prog
  use typedef
  implicit none

  type (my_type) :: complex_type

  complex_type%b = 2.d0 ! This should work
  write(*,*) complex_type%a(), complex_type%b

!  complex_type%a_int = 3    ! This should fail

end program my_prog
like image 41
Alexander Vogt Avatar answered Oct 23 '22 15:10

Alexander Vogt