# Just say no to non-default lower bounds

**URL:** <https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108>\
**Category:** Uncategorized\
**Created:** [July 7, 2023, 12:36am UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108 "2023-07-07T00:36:47Z")\
**Posts on this page:** 12\
**Page:** 3

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 8, 2023, 6:14pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/41 "2023-07-08T18:14:25Z")

</div>

> [@PierU](#):
>
> `c = b` where `c` is either not allocated or allocated with a different size than `b` was illegal code before F2003, thus with an undefined behavior.

The issue here is whether it was strict f90/f95, or whether some or all of the allocatable TR was implemented. In hindsight, this was a mistake by the f95 standards committee. Both the f95 standard and the allocatable TR were done at the same time. There should have been better communications between the various members of the committee regarding that timing, and the f95 standard should have included the contents of the TR, even it it would have required a delay of a few weeks. As it played out, there would not be another standard update for almost 10 years (f2003, which of course was not available until 2005 or so). In that decade, so-called f95 compilers adopted different subsets of the TR features. I think the standard committee was expecting to produce a new revision in the 1998 timeframe, which would have addressed this problem sooner, but that didn’t happen.

The strict f90/f95 treatment of allocatable arrays was very limited. I remember during that time resorting often to using pointers rather than allocatables in order to have portable, lowest common denominator, code. Even compilers that claimed to support the TR often had missing features, so it was difficult to find even the common subset of code that used TR features that would work on several compilers.

Hindsight is 20/20.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [July 8, 2023, 8:17pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/42 "2023-07-08T20:17:33Z")

</div>

I see… But then it was not strict F95.

Did the specifications change between the TR and the final F2003 version?

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 8, 2023, 10:33pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/43 "2023-07-08T22:33:16Z")

</div>

I don’t know, but I expect it did. There was about a 10 year gap in between. Allocate on assignment might be such a feature that was not in the TR but was in f2003, but I’m not sure. Another one was allocatable scalars. I remember having to allocate derived type arrays of size 1 when all I really wanted was a scalar entity. After f2003 features became more common, I went back and changed a bunch of those.

---

<div class="post-metadata">

**Author:** ![rouson](https://avatars.discourse-cdn.com/v4/letter/r/ce7236/32.png) [@rouson](https://fortran-lang.discourse.group/u/rouson)\
**Post date:** [July 11, 2023, 2:15am UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/44 "2023-07-11T02:15:52Z")

</div>

Compiler engineer Peter Klausler has kindly provided some examples that help to clarify some behavior that was described incorrectly in this thread. See

1. [https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90](https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90)
2. [https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo02.f90](https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo02.f90)

Both codes look interesting and enlightening – although I haven’t scrutinized all of the details of the second one.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [July 11, 2023, 5:47am UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/46 "2023-07-11T05:47:56Z")

</div>

> [@rouson](#):
>
> 1. [https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90](https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90)
> 2. [https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo02.f90](https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo02.f90)
> 
> Both codes look interesting and enlightening – although I haven’t scrutinized all of the details of the second one.

I’m not sure the second one can refute the claim that a compiler may reallocate even if the destination shapes fit: only a `loc()` could show that it happens, and even if it doesn’t in the example this is not a proof that the standard prohibits this behavior.

This second example is interesting, though, as it shows the some compilers do not apply correctly the lower bound rules in all cases.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 11, 2023, 3:42pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/47 "2023-07-11T15:42:02Z")

</div>

> [@PierU](#):
>
> This second example is interesting, though, as it shows the some compilers do not apply correctly the lower bound rules in all cases.

The comments in the code in that second example also claim:

```auto
! The conditions in which an allocated left-hand side
! allocatable is reallocated are very clearly specified in the standards
! since F'2003.

```

I do not think that is correct. The situation where the LHS is previously allocated to be the correct shape and bounds is ambiguous. It is unclear if this ambiguity is on purpose (to intentionally allow the compiler to optimize) or if it is unintentional.

---

<div class="post-metadata">

**Author:** ![rouson](https://avatars.discourse-cdn.com/v4/letter/r/ce7236/32.png) [@rouson](https://fortran-lang.discourse.group/u/rouson)\
**Post date:** [July 11, 2023, 4:42pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/48 "2023-07-11T16:42:15Z")

</div>

I hope this thread demonstrates that the rules of using lower bounds other than 1 are sufficiently complicated that people disagree on whether the rules are even clear and it takes quite a lot of discussion to clarify the rules.

I suspect we all adopt certain habits and we understand how the rules apply within those habits. We then construct a mental map of how to navigate the language and what the language means, but if we enter new territory by doing something outside those habits or if someone new edits the code with different habits, it sometimes invalidates our mental map. None of this negates the fact that lower bounds other than 1 feel most natural for certain algorithms. I’m using a lower bound of 0 in code that I inherited and have developed a new set of habits that seem to be working, but I’m very tempted to refactor the code at some point to switch to a lower bound of 1. We’ll see if I ever get around to it…

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 11, 2023, 4:51pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/49 "2023-07-11T16:51:08Z")

</div>

> [@rouson](#):
>
> Compiler engineer Peter Klausler has kindly provided some examples that help to clarify some behavior that was described incorrectly in this thread. See
> 
> 1. [https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90](https://github.com/klausler/fortran-wringer-tests/blob/main/fd-misinfo01.f90)

@rouson,

Good catch with the standardese around array dimensions that have nonzero extents where the `LBOUND` result will be based on the lower bound of the array. However, a zero-sized array will have one or more dimensions with zero extents and the `LBOUND` along those dimensions will be `1`:

 ![image](https://global.discourse-cdn.com/free1/uploads/fortran_lang/original/2X/5/5e906e4f5660369d38c9060decec6f36eb191795.png)

So please see [**above**](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/28) where an attempt is made to address the charge of **misinformation.** Perhaps you will run this by the compiler engineer and see if the correction is still misinformation, or if the standard still has more nuances and complications to offer here.

---

<div class="post-metadata">

**Author:** ![PierU](https://yyz2.discourse-cdn.com/free1/user_avatar/fortran-lang.discourse.group/pieru/32/1848_2.png) [@PierU](https://fortran-lang.discourse.group/u/PierU)\
**Post date:** [July 11, 2023, 9:17pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/50 "2023-07-11T21:17:33Z")

</div>

> [@rouson](#):
>
> I hope this thread demonstrates that the rules of using lower bounds other than 1 are sufficiently complicated that people disagree on whether the rules are even clear and it takes quite a lot of discussion to clarify the rules.

The rules are not that complicated. The only ambiguous point so far is whether allocation on assignment can occur or not when the shapes match, with the possible consequences on the bounds.

---

<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:** [July 11, 2023, 10:52pm UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/51 "2023-07-11T22:52:02Z")

</div>

Three cases where I’ve found non-default lower bounds useful:

- sparse matrices; some solver libraries expect zero-based indexing. E.g. for a [CSR](https://en.wikipedia.org/wiki/Sparse_matrix#Compressed_sparse_row_(CSR,_CRS_or_Yale_format)) matrix, one can use:

```fortran
integer :: ia(0:n), ja(0:nnz-1)

```

for the row and column indexes.

- Halo regions, as already mentioned. I did encounter some surprises here when passing such arrays to subroutines, particularly in the case where the number of halo cells is dynamic.
- Various tables, where properties could be mapped naturally to a range. (For example the properties of moist air in the range between 20 and 100 degrees Celsius)

Michael Wirth has [written](https://craftofcoding.wordpress.com/2022/04/08/fortran-the-greatest-thing-for-arrays-since-bread-came-sliced/) the following about custom bounds:

> In addition, Fortran arrays can be indexed using any starting value, making an the language conform to the algorithm, rather than the other way around (and if you really like arrays that start at zero, you can use them). For anyone looking for a good example of an algorithm that uses negative array indices, look no further than Niklaus Wirth’s classic 8-Queens problem.

He has written a post about the [8-Queens problem](https://craftofcoding.wordpress.com/2023/04/23/the-eight-queens-puzzle-iii-recursion/) too.

---

<div class="post-metadata">

**Author:** ![RonShepard](https://avatars.discourse-cdn.com/v4/letter/r/a3d4f5/32.png) [@RonShepard](https://fortran-lang.discourse.group/u/RonShepard)\
**Post date:** [July 12, 2023, 1:25am UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/52 "2023-07-12T01:25:14Z")

</div>

> [@ivanpribec](#):
>
> He has written a post about the [8-Queens problem](https://craftofcoding.wordpress.com/2023/04/23/the-eight-queens-puzzle-iii-recursion/) too.

I think this subroutine:

```auto
subroutine print()
   do i = 1,8
      write (*,"(I2)",advance="no") x(i)
   end do
   write (*,*)
end subroutine print

```

is the same as

```auto
write (*,'(8I2)') x(:)

```

---

<div class="post-metadata">

**Author:** ![FortranFan](https://avatars.discourse-cdn.com/v4/letter/f/96bed5/32.png) [@FortranFan](https://fortran-lang.discourse.group/u/FortranFan)\
**Post date:** [July 12, 2023, 4:34am UTC](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108/53 "2023-07-12T04:34:59Z")

</div>

> [@RonShepard](#):
>
> `write (*,'(8I2)') x(:)`

Or, especially given the name of the procedure,

```fortran
print "(*(i2:,1x))", x

```

[Previous page](https://fortran-lang.discourse.group/t/just-say-no-to-non-default-lower-bounds/6108.md?page=2)
