1

I know that in Fortran I can declare an array of a number N of elements if N is declared as a parameter before (and so defined to some value).

On the other hand I know I can get a program to accept arguments from the command line with the use of the subroutine get_command_arg.

My question is:

Can I somehow declare an array of a number of elements given by a command when calling the program from the command line?

I'm looking for something like the command line:

./main -30 

where main.f03 would begin with something like:

integer, parameter :: N = get_command_arg(1)
real :: x(N) ...

I'm trying not to define the arrays as allocatable.

2
  • Allocate is the answer. Why not? Commented Nov 24, 2017 at 3:36
  • Use allocatable arrays, read SIZE from command line, convert it to INTEGER and then allocate the array. Commented Nov 24, 2017 at 5:40

2 Answers 2

3

There are certain languages where you can initialize variables and named constants from command line (like chapel), but Fortran is not one of them.

You say "I am trying not to define the arrays as allocatable." but that is the problem. You simply have to. There is no other way.

Your code

integer, parameter :: N = get_command_arg(1)

real :: x(N) ...

is illegal for several reasons.

You cannot put GET_COMMAND_ARGUMENT() into a constant expression because it is not among allowed functions. It does not return compile-time constant values. And parameter initializers must be set at the compile time.

GET_COMMAND_ARGUMENT() is a subroutine, not a function. It can return more stuff, not just the value, but also the length and status. It is not pure and the Fortran standard is trying to use only pure functions. Other things, like RANDOM_NUMBER(), are subroutines. It is a good style to follow in your own programs too.

The only way in Fortran to create arrays that change from run to run is to make the array allocatable or pointer. There are also automatic arrays for local arrays.

Sign up to request clarification or add additional context in comments.

2 Comments

what do you mean when you say that "... the Fortran standard is trying to use only pure functions"?
@ManuelPena All standard intrisic functions are pure. If an intrinsic procedure has side-effects, it is a subroutine.
1

You can do it this way without allocatables. You just have to pass the size (after converting it to an integer) into a subroutine. But really, I see no reason not to use allocatables for something like this.

program main

implicit none

integer :: n,arg_len,istat
character(len=100) :: arg

call get_command_argument(1,value=arg,status=istat)
if (istat/=0) error stop 'error: cannot read first arg'

read(arg,'(I100)',iostat=istat) n
if (istat/=0) error stop 'error: first arg not an integer'

call real_main(n)

contains

    subroutine real_main(n)
    integer,intent(in) :: n
    integer,dimension(n) :: ival
    ival = 1
    write(*,*) ival
    end subroutine real_main

end program main

Example use:

> ./main 1
       1
> ./main 2
       1           1
> ./main 3
       1           1           1

1 Comment

I did mention automatic arrays. The reason is simple. First, to make the array live longer then the subroutine - but you can call everything from real_main. Still ugly to me. Second, to avoid issues with stack size in many compilers. You have to use special flags to place automatic arrays on the heap. The allocatable are much better, much more natural and the program will be easier to extend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.