为什么我不必指定将 Fortran 函数的结果按值传递给我的 C++ 程序?

Why don't I have to specify that the result of a fortran function is being passed by value to my C++ program?

我正在学习 Fortran C++ 互操作性。在这种情况下,我试图编写一个 'wrapper' 函数 (f_mult_wrapper) 来连接我的 'pure' fortran 函数 (f_mult) 和 C++。该函数在我的 C 代码中定义为

double f_mult_by_wrapper(double i, double j);

并称赞

double u=f_mult_by_wrapper(w,r);

我知道我必须指定 f_mult_wrapper 中的输入参数从 C 中按值传递,而 Fortran 通常按引用传递。但是,当我尝试指定结果按值传递时,编译器给我一个错误:在此上下文中需要一个虚拟参数名称。代码按照编写的方式一起工作,但我不完全明白为什么。

module type_example 
    use :: iso_c_binding
    function f_mult(i,j) result(k)
        ! use fortran intrinsic types
        real:: i,j,k
        k = i*j;        
    end function
    
    function f_mult_wrapper(aw,bw) result(cw) bind(c,name="f_mult_by_wrapper");
        real(c_double), VALUE :: aw ! use c binding types. passed by value
        real(c_double), VALUE :: bw
        real(c_double) :: cw
        real :: a,b,c
        a = aw
        b = bw
        c = cw
        c = f_mult(a,b)
        cw = c
    end function
end module

函数结果根本不是函数arguments/parameters。它们的传递方式不同,具体机制取决于 ABI (calling conventions) 及其类型。

在某些 ABI 中,结果在堆栈上传递。在其他 ABI 中,它们是使用寄存器传递的。这涉及实际上可以装入寄存器的简单类型。可以使用指针(在堆栈上或寄存器中)传递更复杂的对象。

通过value/by引用区分来区分,参数的值是直接传递到stack/in寄存器上,还是使用指针间接传递。它不涉及函数 return 值。

有一些更简单的函数可以 C-interoperable 和其他不能互操作的 Fortran 函数,例如函数 returning 数组。这样的 Fortran-specific 功能是以 compiler-specific 的方式实现的。通常,会传递一个隐藏的参数。这样的隐藏参数可能包含一个指针,并且可以使用寄存器或使用堆栈进行传递。详细信息再次取决于特定的 ABI。

有关最常见的 x86 体系结构的调用约定,请参阅 https://en.wikipedia.org/wiki/X86_calling_conventions 32 位和 64 位有几种不同的变体。