Fortran allocatable array

Previously ,I always thinking that a(:) is a suger as a(1:size(a))
but this expmple confuesd me

program main
    implicit none
    integer,allocatable::a(:)
    allocate(a(5))
    a=10
    write(*,*)a
    write(*,*)size(a)
    a(:)=[9,9,9,9]
    write(*,*)a
    a(1:size(a))=[8,8,8]
    write(*,*)a
    a(1:size(a)-2)=[7,7,7,7]
    write(*,*)a
end program main
>! 
           5
          10          10          10          10          10
           9           9           9           9          10
           8           8           8           9          10
           7           7           7           7          10

It is a part of standand,and even for 2d array,

program main
    implicit none
    integer,allocatable::c(:,:)
    allocate(c(4,4))
    c=10
    c(1:size(c,1)-2,1)=[1,2,3,4]
    write(*,"(4I4)")c
end program main
!>
   1   2   3   4
  10  10  10  10
  10  10  10  10
  10  10  10  10

It is hard for boundary check if using allocatable array.

I think this different shape array assignment should be reject.

No, it is not. If you use an array section like a(1:10) or a(:slight_smile: on the left-hand side, then you do not have an allocatable object, so no reallocation can occur. The right-hand side has a particular shape and that should fit in the fixed (!) left-hand side. There is no ambiguity.

A conforming program shall not have the mismatch in shape in intrinsic assignment, the likes of which are shown in the original post.

The onus to conform is placed on the program writer.

But how about a(1:size(a)-2),it’s behavior is not same as a(1:3) , I don’t understand.:cry:

a(:) is definitely equivalent a(1:size(a)) (well actually to a(lbound(a):ubound(a)), but let’s consider here that the lower bound is 1), and will behave exactly the same if the code is standard-conforming.

Assigning an array (or an array sections) to an array section with a size mismatch is not standard conforming and the behavior is undefined. Ideally we would like the compiler to catch non-confirming code at compile time, but it’s not always possible and it depends on how the array sections are written.

If a is a static array

integer a(5)
a(:) = [1, 2, 3]   ! the compiler can easily catch the size mismatch
a(1:5) = [1, 2, 3]   ! the compiler can easily catch the size mismatch
a(1:size(a)) = [1, 2, 3]   ! the compiler can not easily catch the size mismatch

In the 3rd case the upper bound of the array section is an expression, which is evaluated only at run-time. So at compile time the mismatch cannot be detected. One may argue that on this example it would be fairly easy for the compiler to evaluate the expression at compile time, and that would be true. However where’s the limit? For more complex expressions at some point the compiler would have to actually run the code to be able to evaluate them. So in practice expressions are not evaluated at compile time.

If a is allocatable this is even worse. For instance the size of a(:) is not know at compile time.

With an explicit-shape array, it’s more an aspect of the quality of implementation whether a processor detects and reports the shape mismatch at compile-time. I suspect most compilers do so.

It is a dangerous UB. Previously ,I think It can checked at runtime , and a(1:size(a))=[1,2,3] should calculate size(a) firstly. But I am not familiar with complier,may it is hard to check.

By default, compilers do not check many things at runtime, as they are not required to and as it could hurt the performances. However they have compilation options that can enable many runtime checks (still, not all errors are detected). This is mostly useful for debugging.