user1183643
user1183643

Reputation: 49

Determine variable names dynamically according to a string in Fortran

I want to create a dynamic variable name using Fortran.

The variable name will be obtained by concatenating a string and another string/integer. Then I want to use this variable name to store a value or another variable.

e.g.

! assign values to 2 variables

    my_string = h
    my_integer = 1

! perform concatenation resulting in the dynamic variable name,  h1


! Set the value of variable h1 to another integer value

    h1 = 5

Upvotes: 2

Views: 5553

Answers (4)

High Performance Mark
High Performance Mark

Reputation: 78364

I fear that you will not be able to do this. Fortran requires that variables have names and types at compile time. You (or other SOers) may come up with some kludge to simulate what you want, but it will be a kludge.

Why do you want to do this in Fortran ? There are plenty of languages around which do permit this sort of variable declaration.

EDIT

Well, I thought about it some more, and here's a kludge, unfinished. First a UDT for 'dynamic' variables:

type dynamic_var
  character(len=:), allocatable :: label
  class(*), allocatable :: value
end type

declare some space for such variables:

type(dynamic_var), dimension(:), allocatable :: run_time_vars

and, working with your original data

allocate(run_time_vars(10)) ! No error checking, reallocate if necessary
! lots of code
write(run_time_vars(1)%label,'(a1,i1)') my_string, my_integer
allocate(run_time_vars(1)%value, source = my_value)

This compiles, but doesn't run and I'm not going to stay long enough to fix it, I'll leave that as an exercise to anyone who cares.

  • The write to the label field isn't right.
  • The sourced allocation to the value field doesn't seem to work correctly. Might need to write a 'decode' function to use like this:

allocate(run_time_vars(1)%value, source = decode(my_value))

Like I said, it's a kludge.

Upvotes: 4

max
max

Reputation: 564

Clearly, for reasons given above, this is not legit Fortran (and thus you're going into trouble ...). You may use smart (congrats guys!) kludges, but ...

Instead of using variables h concatenated with 1, 2 or whatever number, why not creating array h(1:N) where N does not have to be known at compilation time : you just have to declare array h as a allocatable.

This is, I think, the legit way in Fortran 90+.

Upvotes: 1

Phil H
Phil H

Reputation: 20151

I think you want to use a data structure. If you have pairs or groups of values that go together, then create a derived data type which can hold both. There's an explanation on this page:

http://web.mse.uiuc.edu/courses/mse485/comp_info/derived.html

If you have a list of these pairs (like your string and int above), then you can create an array of these types. Example code below taken from the page linked above:

type mytype
   integer:: i
   real*8 :: a(3)
end type mytype

type (mytype) var

Array:

type (mytype) stuff(3)

var%i = 3
var%a(1) = 4.0d0
stuff(1)%a(2) = 8.0d0

An significant benefit of doing this is that you can pass the pairs/groups of items to functions/subroutines together. This is an important programming principle called Encapsulation, and is used extensively in the Object Oriented programming paradigm.

Upvotes: 3

milancurcic
milancurcic

Reputation: 6241

No, this is not possible in Fortran.

For more information, look into Reflection (computer programming).

Upvotes: 2

Related Questions