【发布时间】:2017-09-07 03:50:32
【问题描述】:
我想找到一种方法让 fortran 方法为可选参数获取一些值,这将使参数看起来不存在于已调用的方法中。
这是一个简化的测试用例,它在 fortran 代码中提炼出问题:
MODULE FortranOptional
USE ISO_C_BINDING
CONTAINS
SUBROUTINE optionaltest(scalar)
REAL(8), OPTIONAL, INTENT(IN) :: scalar
IF (PRESENT(scalar)) THEN
print *, "scalar is present: ", scalar
ELSE
print *, "scalar is NOT present"
END IF
END SUBROUTINE optionaltest
SUBROUTINE optionaltest_c(scalarC) BIND(C, NAME="optionaltest_c")
REAL(C_DOUBLE), OPTIONAL, INTENT(IN) :: scalarC
REAL(8) :: scalar
IF (PRESENT(scalarC)) THEN
print *, "scalarC is present: ", scalarC
scalar = scalarC
ELSE
print *, "scalarC is NOT present"
! Can I do something here to make scalar appear not present in optionaltest()?
END IF
CALL optionaltest(scalar)
END SUBROUTINE optionaltest_c
END MODULE FortranOptional
以及相关的C++测试代码:
extern "C"
{
void optionaltest_c(double*);
}
void testMethod()
{
double v = 5.3;
optionaltest_c(0);
std::cout << "\n";
optionaltest_c(&v);
}
产生:
scalarC is NOT present
scalar is present: 6.9118029901527309E-310
scalarC is present: 5.2999999999999998
scalar is present: 5.2999999999999998
有什么方法可以根据scalarC 的存在来设置scalar 变量,当scalarC 不存在时它看起来不存在?
一些限制:
我宁愿避免 if 语句涉及对
optionaltest的不同调用,因为子例程的实际版本有几个可选参数,这些参数可以单独指定或不指定,从而导致组合爆炸。我无法将
optionaltest子例程直接绑定为 C 函数,因为子例程的实际版本采用了 shape 可选参数,而在我使用的 Fortran 版本中这些参数与 C 不兼容。我无法修改
optionaltest的签名。
【问题讨论】:
-
@francescalus:不幸的是,在实际方法中,必须在转换步骤中进行计算,因此没有直接类似的变量可以简单地传递。
-
也许我可以更好地解释一下:
CALL optionaltest(scalar)在子程序optionaltest_c中是否可能,或者您是否(可能是因为不同的种类/类型)有scalar和scalarC不同的变量? -
CALL optionaltest(scalar)确实出现在optionaltest_c中;你的意思是CALL optionaltest(scalarC)?我不能做后者,因为正如你猜到的那样,标量和标量C 并不完全相同,我不能只通过scalarC。 -
是的,我确实是指
scalarC。出于兴趣(或最佳答案),您能说明编译器和版本吗?正如您所指出的,我们处于可变支持领域。 -
我用的是gfortran 4.4.7,需要写Fortran90规范。
标签: fortran optional-parameters