Subject: hpff-doc: c-interop.tex

From: <[email-masked]> (Henry Zongaro)
Date: Fri, 18 Oct 1996 17:52:43 -0400 (EDT)

---------------------------------------------------------------------------
[email-masked] is a mailing list for HPF 2.0 language specification
authors and editors.  Instructions for adding or deleting yourself from this
list appear at the bottom of this message.
---------------------------------------------------------------------------
Hello,

     Here's the latest revision of c-interop.tex.

Thanks,

Henry

-------------------------------------------------------------------------------

% interop.tex

% Initial Version of June 21, 1996
% Andy Meltzer and Henry Zongaro
% Version 0.1 - July 11, 1996
% Version 0.2 - August 2, 1996
% Version 0.3 - Sept 18, Zosel -
%  generalized some of  text and move to section applying to all languages -
%  this included the map-to syntax.
%  also editing by Mike Delves to add table and quotes on values.
% Version 0.4 - Oct 17, 1996 Zongaro

%\chapter{Approved Extension for HPF Interoperability with C}
% for now - this is a section of another chapter ...

\section{C Language Bindings}
\label{ext-lang-c}

\label{ch-interop}

A common problem faced by Fortran users is the need to call procedures
written in other languages, particularly those written in C or which have
interfaces that can be described by C prototypes.  Although many Fortran
implementations provide methods which solve this problem, these solutions are
rarely portable.

This section defines a method of specifying interfaces to procedures defined
in C that removes most of the common obstacles to interoperability, while
retaining portability.

\subsection{Specification of Interfaces to Procedures Defined in C}

If a user wishes to specify that a procedure is defined by a C procedure,
this is specified with an {\it extrinsic-kind-keyword} of {\tt C}, as specified
in Section \ref{ch-extrinsics}.

For C subprograms for which an
      {\it extrinsic-spec-arg} of {\tt LANGUAGE = "C"} has been specified,
the constraints associated with the syntax for {\em map-to} (\ref{map-to-rule})
are extended as follows:

\begin{constraints}

\item  A function
       shall have a scalar result of type integer, real or
       double precision.

\item  A dummy argument of a procedure
      shall
        not be an assumed-shape
       array, shall not have the {\tt POINTER} attribute, shall not have the
       {\tt TARGET} attribute, nor shall it have a subobject which has the
       {\tt POINTER} attribute.

\item  The bounds of a dummy argument shall not
       be specified by specification expressions which are not constant
       specification expressions, nor shall the character length parameter
       of a dummy argument of such a procedure be specified by a specification
       expression which is not a constant specification expression.

\item  A {\it dummy-arg-list} of a subroutine
       shall not have a {\it dummy-arg}
       which is {\tt *} or a dummy procedure.
\end{constraints}

The value of the {\it char-literal-constant} in the {\tt EXTERNAL_NAME}
specifier gives the name of the procedure as defined in C.  This value need
not be the same as the procedure name specified by the {\it function-stmt}
or {\it subroutine-stmt}.  If {\tt EXTERNAL_NAME} is not specified, it is
as if it were specified with a value which is the same as the procedure name
in lower case letters.

The {\it extrinsic-spec-arg} of {\tt LANGUAGE = "C"} helps a compiler
identify a procedure
that is defined in C, so that it can take appropriate steps to ensure that
the procedure is invoked in the manner required by the C compiler.

\begin{implementors}
A vendor may feel compelled to provide support for more than one C compiler,
if different C compilers available for a system provide different procedure
calling conventions or different data type sizes.  For instance, a vendor's
compiler may provide support for a value of {\tt GNU_C} in the
{\tt LANGUAGE=} specifier,
or it may provide support through the use of compiler switches.
\end{implementors}

\subsection{Specification of Data Type Mappings for C}

The {\em map-to} attribute is the principal feature which facilitates
referencing procedures defined in C from within Fortran programs.  It allows
the user to specify conversions required to associate the actual arguments
specified on the procedure reference with the formal arguments defined by
the referenced procedure.  The attribute has several optional specifiers.  The
{\tt MAP_TO} specifier indicates the type of the C data to which the HPF data
shall
be converted by the compiler; the {\tt PASS_BY} specifier indicates whether a C
pointer to the dummy argument needs to be passed; the {\tt LAYOUT} specifier
indicates for an array whether the array element order needs to be changed from
Fortran's array element ordering to C's.

For C, the constraints associated with {\em map-to} (\ref{map-to-rule})
are extended as follows.

\begin{constraints}

\item The {\tt MAP_TO}
       attribute shall be specified for all dummy arguments and function
       result variables of a {\tt LANGUAGE = "C"} explicit interface.

\item  The  {\it map-to-type-spec} associated with a dummy argument shall be
compatible with the type of the dummy argument.  (See below for compatibility
rules.)

\item  A {\it layout-spec} shall only be specified for a dummy argument
which is an array.

\item  A {\it layout-spec} shall not be specified for an assumed-size array.
\end{constraints}

If the compiler is capable of representing letters in both upper and lower
case, the value specified for a {\it map-to-type-spec}, {\it layout-spec}
or {\it passby-spec} is without regard to case.  Any blanks specified for a
{\it map-to-type-spec}, {\it layout-spec} or {\it passby-spec} shall be ignored
by the compiler for the purposes of determining its value.

%\begin{reviewers}
%I don't believe the following definition of {\tt C_VOID_POINTER} is going to
%work.  This can get us to {\tt void *}, but what about {\tt int *},
%{\tt float *}, etc. that might appear within {\tt struct} definitions?  Or
%do we turn a blind eye and not support them?
%\end{reviewers}

An implementation shall provide a module, {\tt ISO_C}, which shall define a
derived type, {\tt C_VOID_POINTER}.  The components of the {\tt C_VOID_POINTER}
type shall be private.

\begin{users}
The {\tt C_VOID_POINTER} type provides a method of using {\tt void *}
pointers in a program, but does not give the user any way of manipulating
such a pointer in the Fortran part of the program, since I/O cannot be
performed on an object with private components outside the module which defines
the type, neither can the components or structure constructor of such a
structure be used outside of the module which defines the type.
\end{users}

The values permitted for a {\it map-to-type} are {\tt INT}, {\tt LONG},
{\tt SHORT}, {\tt CHAR}, {\tt SIGNED_CHAR}, {\tt FLOAT}, {\tt DOUBLE},
{\tt LONG_DOUBLE},
{\tt CHAR_PTR}, {\tt VOID_PTR}
or a comma-separated list, delimited by parentheses, of any of these values.
The HPF types with which these are compatible,
are shown in the table below.

A {\it map-to-type-spec} which is a parenthesized list of values is
compatible with a dummy argument of derived type if each value in the list
is compatible with the corresponding component of the derived type.

The values permitted for a {\it passby-spec} are {\tt VAL}, {\tt *},
{\tt ** }, {\tt *** } or {\tt **** }.  If the {\it passby-spec}
is not specified, the value {\tt VAL} is assumed.  If a {\it passby-spec} of
{\tt VAL} is specified, the dummy argument shall not have the
{\tt INTENT(OUT)} or {\tt INTENT(INOUT)} attribute specified.  If a value of
{\tt *}, {\tt **}, {\tt ***} or {\tt ****} is specified for the
{\it passby-spec}, an associated actual argument shall be a variable.

The value of the {\it map-to-type-spec} specified for a dummy argument in
the interface body of a procedure for which a {\tt LANGUAGE=} specifier whose
value is {\tt C} appears
shall be such that at
least one of the permitted mapped to types is the same as
the C data type of the corresponding formal argument in the C
definition of the procedure (or a type that is equivalent to one of the
permitted mapped to types).
The C data type of a function in the C
definition of a procedure shall be one of the permitted mapped to types
(or a type that is equivalent to the permitted mapped to types) specified
for the function result variable  in the interface body of a
function with the {\tt LANGUAGE=} specifier whose value is {\tt C}.
  If a subroutine has
been specified with a {\tt LANGUAGE=} specifier whose value is {\tt C}, the C definition
of the procedure shall be specified with a data type of {\tt void}.

%\begin{reviewers}
%I'm not sure how the C standard describes types that are "equivalent".  Anyone
%know the correct terminology?
%\end{reviewers}

The permitted mapped to types for scalar dummy arguments
of intrinsic type or of the derived type {\tt C_VOID_POINTER}, are shown in
the following table.
\vspace{0.3cm}
\begin{center}
\begin{tabular}{|l|l|l|l|l|l|l|} \hline
{\tt MAP_TO = } & {\bf Compatible}  & \multicolumn{5}{c}{{\bf C Type if} {\tt PASS_BY} {\bf =}} \vline \\
 & {\bf With} & {\tt VAL} & * & ** & *** & **** \\ \hline
{\tt INT} & {\tt INTEGER} & int & int* & int** & int*** & int**** \\
{\tt LONG} & {\tt INTEGER} & long & long* & long** & long*** & long**** \\
{\tt SHORT} & {\tt INTEGER} &  short & short* & short** & short*** & short**** \\
{\tt SIGNED_CHAR} & {\tt INTEGER} & signed & signed & signed & signed & signed \\
                  &               & \ \ \ char & \ \ \ char* & \ \ \ char** & \ \ \ char*** & \ \ \ char**** \\
{\tt FLOAT} & {\tt REAL} & float & float* & float** & float*** & float**** \\
{\tt DOUBLE} & {\tt REAL} & double & double* & double** & double*** & double**** \\
{\tt LONG_DOUBLE} & {\tt REAL} & double & double* & double** & double*** & double**** \\
{\tt CHAR} & {\tt CHARACTER(1)} & char & char* & char** & char*** & char**** \\
{\tt CHAR_PTR} & {\tt CHARACTER} & char* & char** & char*** & char**** & char***** \\
{\tt VOID_PTR} & {\tt C_VOID_POINTER} & void* & void** & void*** & void**** & void***** \\  \hline
\end{tabular}
\end{center}
\vspace{0.3cm}

The permitted mapped to types of an array are the same as the permitted mapped
to types of a scalar variable of that type followed by a left bracket
({\tt [}),
followed by the extent of the corresponding dimension of the dummy argument,
following by a right bracket ({\tt ]}), for each dimension of the array.  If
no value is specified for the {\tt LAYOUT=} specifier, the corresponding
dimensions of the dummy argument are determined from right to left; if the
value {\tt C_ARRAY} is specified for the {\tt LAYOUT=} specifier, the
corresponding
dimensions of the dummy argument are determined from left to right.

The permitted mapped to types of a scalar variable of derived type are the
structures whose members are of one of the permitted mapped to types of the
components of the derived type.

If there is a mismatch between the precision, representation method, range of
permitted values or storage sequence between the type of the dummy argument and
the permitted mapped to type of the dummy argument, the compiler shall ensure
that, for the duration of the reference to a procedure defined with a
{\tt LANGUAGE=} specifier whose value is {\tt C}, the dummy argument is represented in
a manner that is compatible with the expectations of the C processor for an
object of the permitted mapped to type.  Upon return from the procedure, the
compiler shall ensure that the value of an actual argument which is a variable
is restored to the specified type and kind.

If the range of permitted values of the type and mapped to type differ and
the value of the actual argument or some subobject of the actual argument is
not within the permitted range of the mapped to type, the value of the
associated dummy argument or subobject becomes undefined.  Conversely, if
the value of the dummy argument or some subobject of the dummy is not within
the permitted range of values of the associated dummy argument, and the
associated actual argument is a variable, the value of the associated actual
argument or subobject of the actual becomes undefined.

\begin{users}
These rules were created to ensure the portability of interoperability.
However, it should be noted that for large objects, a significant overhead may
be incurred if there is a mismatch between the representation method used for
the data type versus the representation method used for the permitted mapped to
type.
\end{users}

\begin{users}
In some cases, this may cause the value of the actual argument to change
without the value being modified by the procedure referenced.  For example,

\CODE
      PROGRAM P
        INTERFACE
          EXTRINSIC(LANGUAGE='C') SUBROUTINE C_SUB(R,I)
            REAL(KIND(1.0D0)), MAP_TO('FLOAT'), PASS_BY('*') :: R
            INTEGER, MAP_TO('INT', '*') :: I
          END SUBROUTINE C_SUB
        END INTERFACE
        REAL(KIND(0.0D0)) RR

        RR = 1.0D0 + 1.0D-10
        I = 123456789
        PRINT *, RR
        CALL C_SUB(RR, I)
        PRINT *, RR
      END PROGRAM P

      void c_sub(float *r, int *i)
      {
      }
\EDOC

Might print

\CODE
 1.00000000010000000
 1.00000000000000000
\EDOC

although the value of {\tt *r} is not modified in {\tt c\_sub}.  Similarly,
the value of {\tt I} might become undefined after the reference to
{\tt c\_sub}, although {\tt *i} is not modified.

Although it is good practice to avoid specifying a mapped to type of
{\tt float} for a dummy argument of any type other than default real, or a
mapped to type of {\tt double} for a dummy argument of any type other than
double precision real, selecting an appropriate dummy argument type
for objects requiring a mapped to type {\tt int} or {\tt long} might not be
so simple.
\end{users}

The value permitted for a {\it layout-spec} is {\tt C_ARRAY}.

If no {\it layout-spec} is specified for a dummy array argument, the array
element order shall be the same as that specified by Fortran.  If the value of
{\it layout-spec} specified is {\tt C_ARRAY}, the array element order of the
array shall be transposed for the duration of the reference to the procedure.

%\begin{reviewers}
%Note that we have no way of specifying {\it layout-spec} for structure
%components.
%\end{reviewers}

\subsubsection{Examples of Data Type Mappings}

Some examples should help to clarify what sorts of C procedure definitions
would be permitted given an interface body in a Fortran program.  For example,
the following interface body

\CODE
        INTERFACE
          EXTRINSIC('C') SUBROUTINE C_SUB(I, R, DARR, STRUCT)
            INTEGER, MAP_TO('INT') :: I
            REAL, MAP_TO('FLOAT'), PASS_BY('*') :: R
            REAL(KIND(1.0D0)), MAP_TO('DOUBLE') :: DARR(10)
            TYPE DT
              SEQUENCE
              INTEGER :: I, J
            END TYPE DT
            TYPE(DT), MAP_TO('(INT, LONG)', '*') :: STRUCT
          END SUBROUTINE C_SUB
        END INTERFACE
\EDOC

could correspond to a C procedure which has the prototype

\CODE
   void c_sub(int i, float r*, double darr[10], struct {int i, long j} *)
\EDOC

In the following example of the {\it layout-spec},

\CODE
      PROGRAM P
        INTERFACE
          EXTRINSIC('C') SUBROUTINE C_SUB(A, B)
            INTEGER, MAP_TO('INT') :: A(2,2)
            INTEGER, MAP_TO('INT'), LAYOUT('C_ARRAY') :: B(2,2)
          END SUBROUTINE C_SUB
        END INTERFACE

        INTEGER :: AA(2,2), BB(2,2)
        CALL C_SUB(AA, BB)
      END PROGRAM P

      void c_sub(int a[2][2], b[2][2])
\EDOC

the correspondence between elements of {\tt AA} and {\tt a}, and elements of
{\tt BB} and {\tt b} is

\CODE
        AA(1,1)   a[0][0]              BB(1,1)   b[0][0]
        AA(2,1)   a[0][1]              BB(2,1)   b[1][0]
        AA(1,2)   a[1][0]              BB(1,2)   b[0][1]
        AA(2,2)   a[1][1]              BB(2,2)   b[1][1]
\EDOC
---------------------------------------------------------------------------
To (un)subscribe to this list, send mail to [email-masked].
Leave the subject line blank, and in the body put the line
(un)subscribe <email-address>
---------------------------------------------------------------------------