El atributo SAVE necesario para las variables Fortran cuando solo la dirección C_LOC se devuelve a un programa C?
fortran-iso-c-binding (1)
Eso es correcto. Guardar es necesario.
Todas las entidades asignables se desasignan cuando el procedimiento finaliza a menos que se save
.
Puede usar pointer
lugar de allocatable
y el objetivo no se desasignará automáticamente. Me parece mejor que save
debido a posibles llamadas múltiples al procedimiento.
Su programa probablemente "funcionó" porque aunque el bloque de memoria fue desasignado, no se sobrescribió. Entonces, el procedimiento C aún encontró datos significativos, pero en la dirección no se le permitió el acceso. Pero este acceso no siempre es controlado por la protección de memoria del sistema operativo.
Normalmente, el atributo SAVE
se utiliza en las declaraciones de tipo Fortran de modo que la variable conserve su valor al final de un subprograma, tal como se describe aquí mediante las respuestas a la pregunta SO. Sin embargo, recientemente dí un ejemplo en otra pregunta sobre cómo se puede escribir una función Fortran que devuelve solo la dirección C de una cadena de caracteres asignados constante a un programa de llamadas C, con las características intrínsecas C_LOC y otras funciones ISO_C_BINDING de F2003. ¿Debería usarse el atributo SAVE
en la constante de cadenas asignables de Fortran para evitar posibles problemas?
Aunque no SAVE
, la función funcionó según lo previsto: el programa C usa un char*
para señalar la dirección devuelta por la función Fortran, que luego podría usarse como normal (por ejemplo, para imprimir y con strlen()
) . No se generaron advertencias / errores. Además, esto parece consistente con la forma en que he visto C_F_POINTER
utilizado en los documentos del compilador y los ejemplos en una pregunta de SO relacionada (es decir, los valores objetivo no tenían el atributo SAVE
attr).
Particularmente desde que se llamó a la función Fortran desde C, no tengo claro si este proceso exhibe el comportamiento esperado, o si podría / debería haber fallado, o si este es un detalle de implementación específico del proveedor. La documentación de Intel Fortran 17 para SAVE
( aquí ) parece indicar que una constante de cadena (asignable o no?) Se guarda por defecto, pero no estoy seguro de si estoy leyendo este derecho, o cómo / si esta información se sostiene en el contexto actual. ¿Estoy realizando este proceso de una manera portátil y correcta?
Aunque ya he vinculado el código, aquí están los bits importantes:
! 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;
}
Compilado como ifort /c f_string.f90
, icl c_string /link f_string.obj
.