Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28434 Discussions

How to catch detection of assignment on non-allocated array?

hkvzjal
New Contributor I
913 Views

Hi,

I found out that ifort (ifx as well) enable the following code to run successfully:

 

 

module test
    implicit none
    logical, allocatable :: array(:)
end module

program main
    use test
    implicit none
    logical :: x
    
    x = .false.
    array(:) = x
    print *, 'hello'
end program

 

 

While GNU gfortran will segfault since array has not been allocated. Which seems to me to be the right behavior as it enables catching a bug in the code.

 

I tried using the flags "-check all -warn all" but the code still runs prompting "hello".

 

Is there something else that I could use to force the compiler to catch that I'm doing an assignment on an uninitialized array?

 

Here a compiler explorer link with this minimal code: https://godbolt.org/z/4MdEc8do5

 

Thanks,

0 Kudos
12 Replies
jdelia
New Contributor I
893 Views

Hi. My first thought is to check that is allocated before using it, e.g.

 

module m_test
  implicit none
  logical, allocatable :: array(:)
end module m_test
!
program test
  use m_test
  implicit none
  logical :: x
  x = .false.
  if (allocated(array)) then
    array (:) = x
  else
    error stop "error: array not allocated"
  end if
  print *, 'hello'
end program test

 

 Then,

 

$ ifx -O2 -error-limit 4 -e03 -fimf-arch-consistency=true -fimf-precision=high -finline-functions -fp-model consistent -fpp -fpe-all=1 -ipo -mavx -mtune=generic -m64 -parallel-source-info=1 -qmkl -qopenmp -qopt-report=3 -standard-semantics -std18 -traceback -WB -warn all -xHost -o testcase-0140-ifx.exe testcase-0140.f90
$ ./testcase-0140-ifx.exe
error: array not allocated

 

I don't know if there is another (portable) way to do it.

Greetings. Jorge.

0 Kudos
jimdempseyatthecove
Honored Contributor III
888 Views

Both ifort and ifx default standard_realloc_lhs, earler versions did not, apparently gfortran does not (it may be using -nostandard_realloc_lhs).

See option standard_realloc_lhs.

 

Jim Dempsey

0 Kudos
hkvzjal
New Contributor I
876 Views

Hi @jimdempseyatthecove, thanks for the clue. Tried using "-nostandard_realloc_lhs" on compiler explorer but I see no difference:

hkvzjal_0-1702477214004.png

 

0 Kudos
hkvzjal
New Contributor I
883 Views

Hi @jdelia ,

Yes, I use if(allocated( )) at initialization of the program. The thing is that the memory allocation+initialization procedure and the actual assignment/use are in separate procedures. I found a place in the code in which it would be possible to do an assignment having inadvertently bypassed the allocation. Thus I was hoping to have an option that would lead to an error like a segfault to detect that a non-allocated array is being used an fix the bug, instead of having the program running.

Cheers,

0 Kudos
Arjen_Markus
Honored Contributor I
865 Views

In the example above the assignment is to an array section, not an allocatable array. Then automatic allocation does not occur, as the left-hand side is not allocatable:

 

array(:) = x

Note also that the right-hand side is a scalar, not an array. I am not sure what the size of the array would become if you do:

array = x

 

0 Kudos
hkvzjal
New Contributor I
861 Views

Hi Arjen,

I'm not looking for automatic allocation, and here I'm just giving a constant value to the whole array.

(this "array = x" has the same behavior as "array(:) = x" for this specific example, that's just fine)

The ideal behavior I'm looking for is a runtime error that would catch the issue just like with gfortran that segfaults.

0 Kudos
Arjen_Markus
Honored Contributor I
852 Views

Ah, but the two are NOT equivalent:

  • With "array = x", the left-hand side is an allocatable object and the rules of automatic reallocation force it to become allocated to a convenient size.
  • With "array(:) = x", the left-hand side is not allocatable, so it should have a definite size, equal to the right-hand side, unless the right-hand side is a scalar.

Here is where gfortran and Intel Fortran differ:

  • gfortran causes a run-time failure.
  • Intel Fortran allocates it to zero size.

I would expect the latter behaviour to be conforming to the standard.

Still, the example program is different and should result in a run-time failure.

Steve_Lionel
Honored Contributor III
853 Views

/check:pointer should have caught this, but it doesn't.  I wondered if the compiler may have thrown away the assignment because it was never used, but that's not the case either.  I consider the lack of an error from /check:pointer a bug.

hkvzjal
New Contributor I
852 Views

Hi @Steve_Lionel that is exactly what I thought as I also tried using that flag and didn't help! thanks for the confirmation!

0 Kudos
Steve_Lionel
Honored Contributor III
849 Views

I note that the debugger shows the array as unallocated/undefined. An allocatable array's allocation status is ALWAYS defined, unlike a pointer.

hkvzjal
New Contributor I
825 Views

Indeed, the debugger shows the array as undefined.

So, as of now it is only possible to catch the bug by doing:

if(allocated(array))then
...
else
!> some error + stop
end if

and putting a break point inside the else. But if someone forgets to put that safeguard, we cannot rely on attaching the debugger to see where it crashes, as it will crash somewhere else, completely unrelated to the actual problem (this is the situation that brough me here).

I would insist on this:


@Steve_Lionel wrote:

(...) I consider the lack of an error from /check:pointer a bug.


 

0 Kudos
jimdempseyatthecove
Honored Contributor III
821 Views

jimdempseyatthecove_0-1702487010313.png

The array was not allocated... but no error was reported.

Now the following is interesting

jimdempseyatthecove_1-1702487158523.png

An unallocated array w/o/(:) assigned to scalar remains unallocated (no error)

Assigned to array, behaves as expected:

jimdempseyatthecove_2-1702487284192.png

 

Jim Dempsey

Reply