Error: Unexpected STATEMENT FUNCTION statement at (1)

I’ve taken a very small portion of code from my big program to show the error on the subject line. How do I get rid of this error if most of this code has to stay. DATAX has to be a two dimensional array.

I’m not allowed to use iso_c_binding!

      INTEGER FUNCTION GUESS(A,B,C,D)
      IMPLICIT NONE
      INTEGER A,B(*),C,D
      INTEGER DATAX,E
      INTEGER I,J
      write(*,*)'   '
      DATAX(I,J)=F(F(G+E)+I)+J
      GUESS=0
      RETURN
      END

#include <stdio.h>
#include <string.h>

void test_(char* z1, int leng);

int main ()
{
}

  gfortran -c -g work.f -o work.o -g -Wall -Werror -fmax-errors=1
  gcc -c -g main.c -o main.o 
  gfortran -g main.o work.o main.exe -Wall -Werror -fmax-errors=1
      DATAX(I,J)=F(F(G+E)+I)+J                                          
                                                                        1
Error: Unexpected STATEMENT FUNCTION statement at (1)
Fatal Error: Error count reached limit of 1.

I think your entire program should be compiled with -std=legacy.

It appears DATAX is intended to be a rank 2 array, but it is declared as an integer scalar. You need to modify the declaration of DATAX to include bounds. I.e.

INTEGER DATAX(I,J), E

Thanks, but “-std=legacy” doesn’t remove the “Unexpected STATEMENT FUNCTION statement at (1)” error!

When I try this, I get the error: "Variable ‘i’ cannot appear in the expression at (1).

Move the statement function data(i,j) = ... above the write(*,*) statement. I’m assuming the write is a remnant of a poor man’s debugging workflow. For more background, check the Oracle documentation on statement functions. Since these are really function-like definitions, they belong in the specification section, before any executable statements like write.

Btw, statement functions have been marked as obsolescent for a while. See Questions about statement functions - #6 by msz59

1 Like

DATAX cannot be declared an array with bounds I,J if I,J are local variables in the function. Its shape must be defined either by a constant compile-time expression or by expression involving dummy arguments (I assume there are no COMMON blocks in teh code

1 Like

msz59 DATAX cannot be declared an array with bounds I,J if I,J are local variables in the function. Its shape must be defined either by a constant compile-time expression or by expression involving dummy arguments (I assume there are no COMMON blocks in teh code

How would you do it with dummy arguments?

This seems to be working. I just have to give the I and J variables initial values of 0 using a DATA statement.

Here is an example:

module m
implicit none
contains
function sum_mat(n1,n2,x) result(xsum)
integer, intent(in) :: n1, n2
real   , intent(in) :: x(n1,n2)
real                :: xsum
xsum = sum(x)
end function sum_mat
end module m

program main
use m, only: sum_mat
implicit none
integer, parameter :: n1 = 2, n2 = 3
real :: x(n1,n2)
call random_number(x)
print*,sum(x),sum_mat(n1,n2,x) ! will give same result
end program main

Ok, so is datax supposed to be an array or is it supposed to be a statement function? How is it used later in the code? Because if it is supposed to be a statement function, then @ivanpribec is correct, it must appear before any executable statements. If it’s supposed to be an array, then you need to figure out what the actual dimensions are supposed to be. It must be at least as big as i and j ever get if that’s the case. Without more of the actual code, I’m afraid it’s near impossible to tell which is the case.

this was in OP first message, so NOT a statement function

datax is an argument to another function. Since it is defined as an integer, datax is also used to access an element in an array.

But, there are many functions that also define datax as an integer (as above) and use it in similar ways.

What’s throwing me off is what appears to be some lack of initialization for the two indices. datax is not in any include file or common statement, but it’s being defined in many routines. It’s like the routines jump around in datax. The routines don’t appear to be sharing data directly using datax. datax appears to be a local variable in many routines.

datax isn’t really named datax. In the code it’s named “DATA”! :innocent:

[msz59]

this was in OP first message, so NOT a statement function But, there are many functions that simply define datax as an integer. All the routines go on to use datax in similar ways.

That was my initial guess.

I’m actually leaning towards DATAX is supposed to be a statement function. In that case, I and J are it’s arguments, not used to index into an array. If DATAX is passed as an argument, is the whole thing passed, or is it used like DATAX(1,2)? The declaration INTEGER DATAX can also mean that DATAX is a function that returns an INTEGER, and so the statement function actually makes sense.

1 Like

everythingfunctional

I’m actually leaning towards DATAX is supposed to be a statement function. In that case, I and J are it’s arguments, not used to index into an array. If DATAX is passed as an argument, is the whole thing passed, or is it used like DATAX(1,2) ? The declaration INTEGER DATAX can also mean that DATAX is a function that returns an INTEGER , and so the statement function actually makes sense.

It is always passed as “DATAX(1,2)”.

Passed? Where? No trace of DATAX being a dummy argument. It is a total mess.

1 Like
DATAX(I,J)=F(F(G+E)+I)+J

is F an external function. If so, try declaring it to be external before the write statement.

external F

DATAX(I,J)=F(F(G+E)+I)+J

I notice that G seems to be not declared

Then it is a statement function, and DATAX(1,2) calls it with arguments (1, 2) and passes the result as the actual argument.