# Arbitrary sized array

**URL:** <https://fortran-lang.discourse.group/t/arbitrary-sized-array/59>\
**Category:** Help\
**Created:** [May 23, 2020, 2:06pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59 "2020-05-23T14:06:36Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [May 23, 2020, 2:06pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/1 "2020-05-23T14:06:36Z")

</div>

Hi all  
I am gonna declare an arbitrary sized one dimensional array in fortran so that the size of array will specify  
by user input. i can not use syntax below:

program main  
integer :: n  
print \*, “Enter a positive integer number:”  
read \*, n  
real, dimension(n) :: a  
…  
…  
…  
end program main

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [May 23, 2020, 3:23pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/2 "2020-05-23T15:23:19Z")

</div>

You need an allocatable array. Its size is determined at run-time:

```auto
program main
  implicit none
  integer :: n
  real, allocatable, dimension(:) :: a
  print *, “Enter a positive integer number:”
  read *, n
  ...
  allocate(a(n))
  … ! work with a 
  deallocate(a)
  ...
end program main

```

So you declare your array as `allocatable`, and then explicitly allocate it with the size you want. When you’re done working with it, deallocate it to free the memory.

If you prefer, you can also omit the `dimension` attribute and declare the array like this:

```auto
real, allocatable :: a(:)

```

It’s a good habit to always include `implicit none` at the beginning of your program.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 23, 2020, 3:25pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/3 "2020-05-23T15:25:20Z")

</div>

No, you need first to declare the array as `allocatable`, then allocate memory once the size is known:

```
real, dimension(:), allocatable :: a
read *,n
allocate(a(1:n))
```

---

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [May 23, 2020, 3:34pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/4 "2020-05-23T15:34:17Z")

</div>

Thanks 🙏 🙏 🙏

---

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [May 23, 2020, 3:34pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/5 "2020-05-23T15:34:35Z")

</div>

Thank you 🙏 🙏 🙏

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [May 23, 2020, 3:56pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/6 "2020-05-23T15:56:01Z")

</div>

Yes! Didn’t spot that. Fixed.

---

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [May 23, 2020, 6:21pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/7 "2020-05-23T18:21:52Z")

</div>

Final program:

 ![largest_smallest_element](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/1X/da9c0f2169edb0667891bc967496a19d7bb8770e.png)

---

<div class="post-metadata">

**Author:** ![milancurcic](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/milancurcic/32/2_2.png) [@milancurcic](https://fortran-lang.discourse.group/u/milancurcic)\
**Post date:** [May 23, 2020, 6:52pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/8 "2020-05-23T18:52:54Z")

</div>

Nice! Now, if you’d like to go for a v2, try:

1. Prompting the user for `n` without resorting to a `goto`;
2. Using intrinsic functions `minval` and `maxval`.

---

<div class="post-metadata">

**Author:** ![ELNS](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/elns/32/3338_2.png) [@ELNS](https://fortran-lang.discourse.group/u/ELNS)\
**Post date:** [May 23, 2020, 6:56pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/9 "2020-05-23T18:56:36Z")

</div>

Nice suggestions 👍

---

<div class="post-metadata">

**Author:** ![parekhvs](https://avatars.discourse-cdn.com/v4/letter/p/9dc877/32.png) [@parekhvs](https://fortran-lang.discourse.group/u/parekhvs)\
**Post date:** [May 24, 2020, 2:32am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/10 "2020-05-24T02:32:29Z")

</div>

By the way, starting with Fortran 2008 and the introduction of the BLOCK construct, it’s also possible to employ an “automatic” array which may be of interest to some readers. Here’s an example: note the automatic array has the scope of the BLOCK construct.

```Fortran
   integer :: n
   print *, "Enter a positive value for n"
   read *, n
   print *, "you entered n=", n
   block
      integer :: a(n)
      integer :: i
      a = [( i, i=1, n )]
      print *, "a = ", a
   end block
end

```

Here’s the processor response to this example

> C:\Temp\>type p.f90  
> integer :: n  
> print \*, “Enter a positive value for n”  
> read \*, n  
> print \*, “you entered n=”, n  
> block  
> integer :: a(n)  
> integer :: i  
> a = [( i, i=1, n )]  
> print \*, "a = ", a  
> end block  
> end
> 
> C:\Temp\>gfortran -Wall p.f90 -o p.exe
> 
> C:\Temp\>p.exe  
> Enter a positive value for n  
> 5  
> you entered n= 5  
> a = 1 2 3 4 5
> 
> C:\Temp\>

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 24, 2020, 8:49am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/11 "2020-05-24T08:49:08Z")

</div>

Interesting, can you tell us what are the purposes of BLOCK…END BLOCK ?

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 24, 2020, 9:01am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/12 "2020-05-24T09:01:31Z")

</div>

@ELNS  
A piece of code without goto (I don’t want to troll about goto 😉 but I think the code will be clearer because of the indentation):

```auto
    do
        print *, "Enter a positive value for n"
        read *, n
        if (n > 0) exit
    end do

```

Note that in Fortran there is no `repeat...until` or `do...while` (with the while at the end) loops.  
You could of course also use the old trick:

```auto
    n = -1
    do while (n<=0)
        print *, "Enter a positive value for n"
        read *, n
    end do

```

But this is less elegant than the `exit` solution because the statement `n=-1` is arbitrary: `n=-2020` or `n=-314159265` would do the job as well. If the language offers an elegant solution then use it, if it does not, find a trick.  
Note that there is also the `cycle` statement to go to the next iteration of a loop.

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [May 24, 2020, 4:31pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/13 "2020-05-24T16:31:18Z")

</div>

My understanding is that the `block` construct simply allows programmers to organise code by grouping declarations and statements together within a defined local scope. This can have some advantages:

- It avoids large declaration blocks at the beginning of programs and procedures;

- it is easier to reason which variables are used in which execution statements when reading the code;

- it limits the scope of variables so they can’t accidentally be used elsewhere;

- it can be useful for objects with finalizers since these will be called at `end block` if the objects are declared within the `block`.

I don’t believe there is any tacit memory or speed advantage to using `block` constructs, they are just for programmer comfort.  
The main argument against using `block` constructs IMHO is that a procedure would provide the same advantages in terms of code organisation, while also being reusable (callable) whereas a `block` construct is not.

---

<div class="post-metadata">

**Author:** ![vmagnin](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/vmagnin/32/28_2.png) [@vmagnin](https://fortran-lang.discourse.group/u/vmagnin)\
**Post date:** [May 24, 2020, 4:36pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/14 "2020-05-24T16:36:59Z")

</div>

Thank you @lkedward for that answer. Do you think there could be a speed impairment if a `block` is repeated a lot of time in a loop ? (if its variables need to be allocated at each iteration)

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [May 24, 2020, 5:10pm UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/15 "2020-05-24T17:10:02Z")

</div>

I would expect a slow down if you are declaring large arrays with dimensions only known at runtime (just like @parekhvs’s example above) - though this is true regardless of if you’re using a block construct.

However if the variables are scalar or the array size is a compile-time constant, then I would expect the compiler to be able to optimise this (i.e. allocate once). Unfortunately I’m no compiler expert, so this is my best guess.

---

<div class="post-metadata">

**Author:** ![simong](https://avatars.discourse-cdn.com/v4/letter/s/df788c/32.png) [@simong](https://fortran-lang.discourse.group/u/simong)\
**Post date:** [June 13, 2020, 9:41am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/16 "2020-06-13T09:41:11Z")

</div>

If you want to have thread-local variables inside a **do concurrent** you have to use the **block** construct.

---

<div class="post-metadata">

**Author:** ![ivanpribec](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/ivanpribec/32/3290_2.png) [@ivanpribec](https://fortran-lang.discourse.group/u/ivanpribec)\
**Post date:** [June 13, 2020, 10:38am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/17 "2020-06-13T10:38:27Z")

</div>

Another great usage of `block` that @lkedward pointed out to me is to prevent name clashes between intrinsic functions and named variables by introducing a new local scope. An example can be found in the discussion [Best practices for passing C strings](https://fortran-lang.discourse.group/t/best-practices-for-passing-c-strings/104/12).

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [June 13, 2020, 11:01am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/18 "2020-06-13T11:01:08Z")

</div>

Would that approach be equivalent to using the `LOCAL` clause to specify variable locality in `DO CONCURRENT`?

_e.g._

```auto
do concurrent (i=1,10) local(x)
...

```

---

<div class="post-metadata">

**Author:** ![simong](https://avatars.discourse-cdn.com/v4/letter/s/df788c/32.png) [@simong](https://fortran-lang.discourse.group/u/simong)\
**Post date:** [June 13, 2020, 11:31am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/19 "2020-06-13T11:31:46Z")

</div>

I didn’t know about that addition for 2018 so thanks for the heads-up. The syntax seems to be very similar to that of openmp (a good thing). Nevertheless I’d say that the block construct gives you more, particularly if there are many variables or more sophisticated initializations.

```
do concurrent (i=1,10)
    block
        integer :: a, b
        call load_start_values(a,b)
        ....
    end block
end do
```

---

<div class="post-metadata">

**Author:** ![lkedward](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/lkedward/32/72_2.png) [@lkedward](https://fortran-lang.discourse.group/u/lkedward)\
**Post date:** [June 13, 2020, 11:38am UTC](https://fortran-lang.discourse.group/t/arbitrary-sized-array/59/20 "2020-06-13T11:38:59Z")

</div>

> [@simong](#):
>
> I’d say that the block construct gives you more, particularly if there are many variables or more sophisticated initializations.

I agree - I don’t use `do concurrent` but my experience with OpenMP is that the locality clauses can quickly get long; by comparison the `block` construct is much cleaner and more readable.
