Normally, the SAVE
attribute is used in Fortran type declarations so that the variable retains its value at the end of a subprogram, such as described by the answers to the SO question here. However, I recently gave an example at another question for how a Fortran function can be written that returns only the C address of an allocatable character string constant to a C calling program, with the C_LOC intrinsic and other ISO_C_BINDING features of F2003. Should the SAVE
attribute be used on the Fortran allocatable string constant to avoid potential issues?
Although I didn't use SAVE
, the function worked as intended: the C program uses a char*
to point at the address returned by the Fortran function, which could then be used as normal (e.g., for printing and with strlen()
). No warnings/errors were generated. Also, this seems consistent with how I have seen C_F_POINTER
used in the compiler docs and the examples at a related SO question (that is, the target values did not have the SAVE
attr).
Particularly since the Fortran function was called from C, it's not clear to me whether this process exhibits the expected behavior, or if it could/should have failed, or if this is a vendor-specific implementation detail. The Intel Fortran 17 documentation for SAVE
(here) seems to indicate that a string constant (allocatable or not?) is saved by default, but I am not sure if I'm reading this right, or how/if this info holds up in the current context. Am I performing this process in a portable, correct manner?
Although I linked to the code already, here are the important bits:
! f_string.f90: returns the C address to an allocatable string constant:
function get_string() bind(c, name='get_string')
use, intrinsic :: iso_c_binding
implicit none
type(C_PTR) :: get_string
character(len=:), allocatable, target :: fortstring ! <- Include SAVE?
fortstring = "Hello StackOverflow" // C_NULL_CHAR ! <- NULL-terminated string constant
get_string = C_LOC(fortstring)
end function get_string
// c_string.c: uses a char* to point at the address returned by 'get_string'
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *get_string(void); // <- Fortran fcn signature
int main(){
char *mycharptr;
mycharptr = get_string();
printf("String from Fortran: %s\n", mycharptr);
printf("len = %d\n", strlen(mycharptr));
return 0;
}
Compiled as ifort /c f_string.f90
, icl c_string /link f_string.obj
.