By default, Intel Fortran passes a hidden length argument for strings. The hidden length argument consists of an unsigned 4-byte integer (IA-32 systems) or unsigned 8-byte integer (Intel® EM64T and Itanium®-based systems), always passed by value, added to the end of the argument list. You can alter the default way strings are passed by using attributes.
The following table shows the effect of various attributes on passed strings:
Effect of ATTRIBUTES Properties on Character Strings Passed as Arguments
Argument |
Default |
C |
C, REFERENCE |
---|---|---|---|
String |
Passed by reference, along with length |
First character converted to INTEGER(4) and passed by value |
Passed by reference, along with length |
String with VALUE option |
Error |
First character converted to INTEGER(4) and passed by value |
First character converted to INTEGER(4) and passed by value |
String with REFERENCE option |
Passed by reference, possibly along with length |
Passed by reference, no length |
Passed by reference, no length |
The important things to note about the above table are:
Character strings without the VALUE or REFERENCE attribute that are passed to routines declared with ATTRIBUTES C are not passed by reference. Instead, only the first character is passed and it is passed by value.
Character strings with the VALUE option passed to routines declared with ATTRIBUTES C are not passed by reference. Instead, only the value of the first character is passed.
For string arguments with default ATTRIBUTES, ATTRIBUTES C, or REFERENCE:
When -nomixed_str_len_arg is set, the length of the string is pushed (by value) on the stack after all of the other arguments.
When -mixed_str_len_arg is set, the length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
For string arguments passed by reference with default ATTRIBUTES:
When -nomixed_str_len_arg is set, the length of the string is not available to the called procedure.
When -mixed_str_len_arg is set, the length of the string is pushed (by value) on the stack immediately after the address of the beginning of the string.
Since all strings in C are pointers, C expects strings to be passed by reference, without a string length. In addition, C strings are null-terminated while Fortran strings are not. There are two basic ways to pass strings between Fortran and C: convert Fortran strings to C strings, or write C routines to accept Fortran strings.
To convert a Fortran string to C, choose a combination of attributes that passes the string by reference without length, and null terminate your strings. For example:
The following example shows the extension of using the null-terminator for the string in the Fortran DATA statement (see "C Strings" in the Intel® Fortran Language Reference):
INTERFACE SUBROUTINE Pass_Str (string) !DEC$ ATTRIBUTES C, ALIAS:'Pass_Str' :: Pass_Str CHARACTER*(*) string !DEC$ ATTRIBUTES REFERENCE :: string END SUBROUTINE END INTERFACE CHARACTER(40) forstring DATA forstring /'This is a null-terminated string.'C/
DATA forstring /'This is a null-terminated string.'C/
The C interface is:
void
Pass_Str (char *string)
To get your C routines to accept Fortran strings, C must account for the length argument passed along with the string address. For example:
! Fortran code
INTERFACE
SUBROUTINE Pass_Str (string)
CHARACTER*(*) string
END INTERFACE
The C routine must expect two arguments:
void
pass_str (char *string, unsigned int length_arg )
This interface handles the hidden-length argument, but you must still reconcile C strings that are null-terminated and Fortran strings that are not. In addition, if the data assigned to the Fortran string is less than the declared length, the Fortran string will be blank padded.
Rather than trying to handle these string differences in your C routines, the best approach in Fortran/C mixed programming is to adopt C string behavior whenever possible.
Fortran functions that return a character string using the syntax CHARACTER*(*)
place a hidden string argument and the length of the string at the beginning
of the argument list.
C functions that implement such a Fortran function call must declare this hidden string argument explicitly and use it to return a value. The C return type should be void. However, you are more likely to avoid errors by not using character-string return functions. Use subroutines or place the strings into modules or global variables whenever possible.
If a Fortran program expects a function to return data of type CHARACTER, the Fortran compiler adds two additional arguments to the beginning of the called procedure's argument list:
The first argument is a pointer to the location where the called procedure should store the result.
The second is the maximum number of characters that must be returned, padded with white spaces if necessary.
The called routine must copy its result through the address specified in the first argument. Example that follows shows the Fortran code for a return character function called MAKECHARS and corresponding C routine.
Example of Returning Character Types from C to Fortran
Fortran code |
Corresponding C Routine |
In the above example, the following restrictions and behaviors apply:
The function's length and result do not appear in the call statement; they are added by the compiler.
The called routine must copy the result string into the location specified by result; it must not copy more than length characters.
If fewer than length characters are returned, the return location should be padded on the right with blanks; Fortran does not use zeros to terminate strings.
The called procedure is type void.