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

Variable Declarations after Executable Section


I'm trying to write a precompiler that processes a bunch of variable declarations in an include file.  These variables are tied to shared memory so I also need to do  a bunch of call C_F_POINTER. Then the FORTRAN file contains some variable declarations of their own.  So I have something like this in the include file:

      REAL*8, POINTER :: F0
      call C_F_POINTER (SM02, SMARR02, [2000])
      call C_F_POINTER(C_LOC(SMARR02(1)), F0)

And something like this in the FORTRAN file:

include ''
ABC1 = F0

This unfortunately complains : A specification statement cannot appear in the executable section

Is there another way to create my precompiler to process my variable in the include file?  It would be nice is FORTRAN could mix declarations and executable sections.





0 Kudos
3 Replies
Black Belt Retired Employee

Perhaps it would be nice, but it doesn't. You'll just have to live with that.

Typically the way one would handle what you're doing is to generate a module with an initialization procedure that is then called from the executable section. The code would then USE the module and, later in the execution section, call the procedure.

Black Belt

Merik G., your precompiler could write two include files instead of just one. The first include file would contain only the declarations of the generated pointer variables, and the second include file could contain all the generated calls to C_F_POINTER. You could use appropriately placed INCLUDE statements for these two files so that all declarations precede all executable statements.

Honored Contributor II

@Merik G.,

If you really need to do as you indicate in your original post, look into BLOCK construct in Fortran; this is assuming the scope of your object ABC1 can be confined in such a BLOCK:

But note since you are working with shared data from a companion C processor, look into standard interoperability with C features in Fortran and see if you can have all interoperable data types for your objects.  Here's a simple example:

#include <stdio.h>

// Fortran function prototype
extern void Fsub( double *, size_t );
#define SIZE(x)  (sizeof(x) / sizeof((x)[0]))

int main() {

    double d[2];
    size_t size_d;

    size_d = (size_t)SIZE(d);
    for ( size_t i=0; i < size_d; i++ ) d = 42.0;

    Fsub(d, size_d);

    return 0;
module m

   use, intrinsic :: iso_c_binding, only : c_double, c_ptr, c_size_t, c_f_pointer

   implicit none


   public :: Fsub


   subroutine Fsub(ptr_d, size_d) bind(C, name="Fsub")

      ! Argument list
      type(c_ptr), intent(in), value       :: ptr_d
      integer(c_size_t), intent(in), value :: size_d

      include "d.f90"
      blk_d0: block
         real(c_double) :: d0
         d0 = d(1)
         print *, "blk_d0: d0 = ", d0
      end block blk_d0

      d => null()


   end subroutine Fsub

end module m

Include file d.f90:

      real(c_double), pointer :: d(:)
      call c_f_pointer( cptr=ptr_d, fptr=d, shape=[ size_d ])

Upon execution with Intel Fortran:

 blk_d0: d0 =  42.0000000000000


However given the facilities in Fortran, it's unclear why you need INCLUDE files.  You can set up the data for use by Fortran all in one place, so the C_F_POINTER instructions need only be done once which then renders moot the INCLUDE sections.