# Fortran Best Practice Minibook

**URL:** <https://fortran-lang.discourse.group/t/fortran-best-practice-minibook/1790>\
**Category:** Announcements\
**Created:** [September 5, 2021, 10:10am UTC](https://fortran-lang.discourse.group/t/fortran-best-practice-minibook/1790 "2021-09-05T10:10:41Z")\
**Posts on this page:** 1\
**Showing post:** 8

<div class="post-metadata">

**Author:** ![certik](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/certik/32/4_2.png) [@certik](https://fortran-lang.discourse.group/u/certik)\
**Post date:** [September 7, 2021, 8:43pm UTC](https://fortran-lang.discourse.group/t/fortran-best-practice-minibook/1790/8 "2021-09-07T20:43:40Z")

</div>

This is the same question I asked 10 years ago. Here are the two relevant parts:

- [Arrays - Fortran Programming Language](https://fortran-lang.org/learn/best_practices/arrays)
- [Fortran Best Practices — Fortran90 1.0 documentation](https://www.fortran90.org/src/best-practices.html#arrays)

I use the assumed-shape in my codes following this recommendation. However, I wonder if explicit-shape is not better after all:

- It specifies the exact dimensions of all arrays (in and out) at _compile_ time using _runtime_ variables `n`, `m`, `l`, etc.
- This helps the reader (me) to see what the dimensions are right away.
- It eliminates the need to manually check that a square matrix was passed into a subroutine that expects `A(:,:)` (and give an error message otherwise), since one can declare it as `X(n,n)`, and then the compiler itself can simply give a runtime error if an incompatible array is passed in.
- I also wonder if this might allow some potential compiler optimizations.
- And it definitely would allow compiler checks for things like `matmul` (as well as all my functions that use explicit-shape). You do not get any such compile time checks if you pass arrays to `matmul` with incompatible dimensions, because the compiler does not know until runtime.

The only downside is that an array temporary is created if you pass in non-continguous data. However, in practice I always end up with contiguous arrays. Except when prototyping, but in that case I don’t mind the array temporary.

I wonder if explicit-shape and assumed-shape arrays cannot simply be united:

- Potentially allow non-contiguous implementation of explicit-shape (thus no array temporaries), unless `bind(c)`, or if interfacing legacy Fortran such as the Lapack library (via `interface`, possibly one could require the `contiguous` keyword for that)
- Allow to allocate explicit-shape

The last point would be very helpful, consider this code:

```fortran
integer :: n
real(dp), allocatable :: X(n,n), Y(n,n)
...
integer :: m
read (*,*) m
allocate(X(m,m), Y(m,m))

```

This would check at runtime (with bounds checking enabled) that the array dimensions are conforming, i.e., that X and Y have exactly the same dimensions, and are square matrices.

One issue is what to do with the variable `n`, such as what happens if one assigns to it. One possible solution:

```fortran
real(dp), allocatable :: X(size(X,1),size(X,1)), Y(size(X,1),size(X,1))

```

However, it is a lot more readable if the variable `n` is used. Another solution is:

```fortran
integer, dim :: n
real(dp), allocatable :: X(n,n), Y(n,n)

```

which can also be used in subroutines as:

```fortran
subroutine sub(X, Y)
integer, dim :: n = size(X,1)
real(dp), intent(in) :: X(n,n)
real(dp), intent(out) :: Y(n,n)
! No need for these checks:
! if (size(X,1) /= size(X,2)) error stop
! if (size(Y,1) /= size(Y,2)) error stop
! if (size(X,1) /= size(Y,1)) error stop
end subroutine

```

Also, not everything can be checked even in `matmul` at compile time, such as when the two arrays declared as:

```auto
integer :: n, m
real(dp), allocatable :: X(n,n), Y(m,m)
Z = matmul(X, Y)

```

But I think a lot more things could be checked. And even in this case, the compiler now knows the runtime constrain `n == m`, and so can use it for example to give an error message much earlier (say when the `n` and `m` is read from a file and it happens that `n /= m`).

---

_[View the full topic](https://fortran-lang.discourse.group/t/fortran-best-practice-minibook/1790)._
