只有C_LOC地址返回给C程序时,Fortran变量需要SAVE属性吗?

时间:2017-06-08 17:13:41

标签: fortran fortran-iso-c-binding

通常,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调用的,所以我不清楚这个过程是否表现出预期的行为,或者它是否可能/应该失败,或者这是否是特定于供应商的实现细节。 SAVEhere)的英特尔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.f90icl c_string /link f_string.obj

1 个答案:

答案 0 :(得分:2)

这是正确的。保存是必要的。

当程序退出时,所有可分配的实体都将被释放,除非它们是save

您可以使用pointer代替allocatable,目标不会自动解除分配。我发现它比save更好,因为可能多次调用该过程。

你的程序可能已经工作了#34;因为虽然内存块已被释放,但它没有被覆盖。所以C程序仍然找到了有意义的数据,但在地址上它不允许访问。但是,操作系统内存保护并不总能检查此访问权限。