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

parameter, bind(c) for arrays

Tobias_Loew
Novice
419 Views

I'm doing mixed C++/FORTRAN development and reference FORTRAN symbols from static libs in C++ code. During regression test for switching from VS2012/IF2013 to VS2015/IF2016 I had to add BIND(C) to all exported functions/procedures (due to a change of the call-semantics for VALUE-tagged parameters). Since I also reference parameter-arrays I tried to also "BIND(C)" them but got an error and found https://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/291657 , but there only scalar-constants are mentioned. My question is: Since I can't BIND(C) parameter-arrays, is there any guarantee on the layout of parameter-arrays (resp. is there a way to enforce a special layout)?

0 Kudos
4 Replies
Lorri_M_Intel
Employee
419 Views

By "parameter arrays", do you mean arrays that are declared with the attribute PARAMETER, and are considered to be compile-time constants.

Or, do you mean arguments to a function/subroutine, where those arguments are arrays.

If you mean the former (compile-time constants) there is no way to BIND(C) them, and in fact, they don't "live" beyond the compilation of that source file.

If you mean the latter (dummy argument to a routine) I'm not sure what sort of problems you've seen with layout, per se.   Can you post a small example?

                --Lorri

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
419 Views

If your Fortran code has parameter arrays, and you wish to pass them as an argument, then as Lorri points out, these arrays are compile time constants and do not live as data stored in memory (thus not referencable). You might be able to use ()'s to encapsulate the parameter array argument to instantiate an array temporary, but this may also be sensitive to compiler option. If this fails, then you should be able to create your own temporary that is not parameter, copy into it, and then pass that.

Please report success/fail of your attempts (for others to learn).

Jim Dempsey

0 Kudos
IanH
Honored Contributor II
419 Views

If an object that is a PARAMETER (a constant) is passed as an actual argument, then the compiler will automatically arrange for the value of the object to exist in memory somewhere, and argument passing will work as normal.  There is no need to manually try and create a temporary for argument passing.

In the case of a data object interoperating with a C global variable, the Fortran data object must be a variable (i.e. it cannot have the PARAMETER attribute).  But that variable can have been initialized by a constant, or have had its value assigned to it from a constant.

0 Kudos
JVanB
Valued Contributor II
419 Views

Actually, you can pass named constants which are arrays as actual arguments, no parentheses required. Such a constant array is just another expression, like 1 or 1.0 or '1' and the compiler will write the constant to a temporary memory location and then pass the address of that location to effectively pass the constant array as an actual argument. Test required:

program P
   implicit none
   integer, dimension(3,3), parameter :: A = reshape([ &
      1, 2, 3, &
      4, 5, 6, &
      7, 8, 9], &
      shape = shape(A), order = [2,1])
   character(30) fmt

   write(fmt,'(*(g0))') '(a/',size(A,2),'(i2))'
   write(*,fmt) 'A =', transpose(A)
   call S(A)
   write(fmt,'(*(g0))') '(a/',size(A,2),'(i2))'
   write(*,fmt) 'A =', transpose(A)
end program P

subroutine S(x)
   implicit none
   integer x(3,3)
   x(2,2) = 0
end subroutine S

Output with ifort /nologo /assume:protect_constants const_test.f90

A =
 1 2 3
 4 5 6
 7 8 9
A =
 1 2 3
 4 0 6
 7 8 9

Output with ifort /nologo /assume:noprotect_constants const_test.f90

A =
 1 2 3
 4 5 6
 7 8 9
A =
 1 2 3
 4 5 6
 7 8 9

So /assume:noprotect_constants has the effect of passing a copy of the array by reference. With /assume:protect_constants, my recollection is that the original behavior was that the array was kept in read-only memory and that a program such as the above would cause a crash at runtime. But there was an issue where standard-conforming code could cause copy-in/copy-out of a section of such an array so that a valid program could crash.

ifort could have implemented some runtime checks to avoid crashing in such a case, and they probably should have because similar code starting with a constant character variable, cast as a character array via the new f2003 sequence association rules, and then copied in and out by standard-conforming code still causes a crash an runtime.

But the runtime checks require precious resources to implement and tend to slow down programs (although hopefully not very much) so ifort is left in this in-between situation where nonconforming code can rewrite constant arrays without warning sometimes but yet conforming code can still crash at copy-out. Didn't the third law of thermodynamics hint that we might not live in a perfect universe?

 

0 Kudos
Reply