Named constants as components of a derived data type

Fortran 90 does not seem to allow named constants in derived data types. It's 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 that parameter approval is not allowed in derived type definitions.

When I delete the parameter keyword, everything works fine. But how can I make sure component a not modified elsewhere?

+6
source share
4 answers

According to the Standard, this is prohibited. The component attribute specifier can only be pointer and dimension for Fortran 90/95 (section 4.4.1), additionally allocatable in Fortran 2003 (section 4.5.3), as well as codimension and contiguous for Fortran 2008 (section 4.5.4.1).

You can get the documents here .

I ran into a similar problem with the target specifier, which is also not resolved.

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 
+5
source

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

+4
source

Question: Why do you want to do this?

Imagine you want to create an array of 1000 my_type values. The result is that the value of a would be stored 1000 times. This is a waste of almost 4kb of memory (assuming int4 ). It would be best to define a parameter in the appropriate module.

Btw, in Modern Fortran's book by Clerman and Spector, Rule No. 133 states that you must define each derived type in its own module. This would be a great place to be so permanent.

+3
source

You can define it as private and create a get () function, but not a set () function. This way your data will be well encapsulated.

+1
source

Source: https://habr.com/ru/post/955370/


All Articles