通常,SAVE
属性用于Fortran类型声明,以便变量在子程序结束时保留其值,例如SO问题here的答案所描述的。但是,我最近在another question给出了一个示例,说明如何编写Fortran函数,该函数只返回 可分配字符串常量的C地址到C调用程序,C_LOC固有和F2003的其他ISO_C_BINDING功能。是否应在Fortran可分配字符串常量上使用SAVE
属性以避免潜在问题?
虽然我没有使用SAVE
,但该函数按预期工作:C程序使用char*
指向Fortran函数返回的地址,然后可以将其用作正常(例如,用于打印和使用strlen()
)。没有生成警告/错误。此外,这似乎与我在编译器文档中使用C_F_POINTER
以及相关SO question中的示例(即目标值没有SAVE
attr)的方式一致。
特别是因为Fortran函数是从C调用的,所以我不清楚这个过程是否表现出预期的行为,或者它是否可能/应该失败,或者这是否是特定于供应商的实现细节。 SAVE
(here)的英特尔Fortran 17文档似乎表明默认情况下保存了字符串常量(可分配或不可分配?),但我不确定我是否正确读取此权限,或者如何/如果此信息在当前上下文中保持不变。我是否以便携,正确的方式执行此过程?
虽然我已经链接到代码,但这里有重要的部分:
! 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;
}
编译为ifort /c f_string.f90
,icl c_string /link f_string.obj
。
答案 0 :(得分:2)
这是正确的。保存是必要的。
当程序退出时,所有可分配的实体都将被释放,除非它们是save
。
您可以使用pointer
代替allocatable
,目标不会自动解除分配。我发现它比save
更好,因为可能多次调用该过程。
你的程序可能已经工作了#34;因为虽然内存块已被释放,但它没有被覆盖。所以C程序仍然找到了有意义的数据,但在地址上它不允许访问。但是,操作系统内存保护并不总能检查此访问权限。