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

SAVE attribute needed for Fortran variables when only the C_LOC address is returned to a C program?

通常,SAVE 属性用于 Fortran 类型声明,以便变量在子程序结束时保留其值,如 SO 问题 here. However, I recently gave an example at 的答案所述如何编写 Fortran 函数 returns 可分配字符串常量的 C 地址到 C 调用程序,具有 C_LOC 内在和其他 ISO_C_BINDING F2003的特点。是否应在 Fortran 可分配字符串常量上使用 SAVE 属性以避免潜在问题?

虽然我没有使用 SAVE,但该函数按预期工作:C 程序使用 char* 指向 Fortran 函数返回的地址,然后可以将其用作正常(例如,用于打印和 strlen())。没有生成 warnings/errors。此外,这似乎与我在编译器文档和相关 SO question 的示例中看到的 C_F_POINTER 的使用方式一致(也就是说,目标值没有 SAVE 属性) .

特别是因为 Fortran 函数是从 C 调用的,所以我不清楚这个过程是否表现出预期的行为,或者它是否 could/should 失败了,或者这是否是特定于供应商的实现细节。 SAVE (here) 的英特尔 Fortran 17 文档似乎表明默认情况下保存了一个字符串常量(可分配或不可分配?),但我不确定我是否正确阅读,或者how/if 此信息在当前上下文中成立。我是否以便携、正确的方式执行此过程?


虽然我已经链接到代码,但这里是重要的部分:

! 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 Whosebug" // 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

没错。需要保存。

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

您可以使用 pointer 而不是 allocatable 并且不会自动释放目标。我发现它比 save 更好,因为可能会多次调用该过程。

你的程序可能 "worked" 因为虽然内存块被释放,但它没有被覆盖。所以 C 程序仍然找到了有意义的数据,但在地址上不允许它访问。但是 OS 内存保护并不总是检查此访问。