Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran:intent(out)和假定大小参数_Fortran - Fatal编程技术网

Fortran:intent(out)和假定大小参数

Fortran:intent(out)和假定大小参数,fortran,Fortran,假设子例程中修改了一个伪参数,而子例程不关心它的初始值。对于标准数字类型的标量(无组件),intent(out)是正确的,对吗 现在,如果伪参数是可分配的,并且子例程取决于其分配状态,或者如果它有未被子例程修改但应保持其初始值的组件(即未定义),或者类似地,如果它是一个数组且子例程中未设置所有元素。。。那么正确的意图应该是intent(inout) 我的问题是,如果伪参数是假定大小的数组(dimension(*)),会发生什么?假设子例程中并非所有元素都被修改,并且希望其他元素保留其初始值,in

假设子例程中修改了一个伪参数,而子例程不关心它的初始值。对于标准数字类型的标量(无组件),
intent(out)
是正确的,对吗

现在,如果伪参数是可分配的,并且子例程取决于其分配状态,或者如果它有未被子例程修改但应保持其初始值的组件(即未定义),或者类似地,如果它是一个数组且子例程中未设置所有元素。。。那么正确的意图应该是
intent(inout)

我的问题是,如果伪参数是假定大小的数组(
dimension(*)
),会发生什么?假设子例程中并非所有元素都被修改,并且希望其他元素保留其初始值,
intent(out)
是否合适?我的推理是,子例程不“知道”数组的大小,因此它不能像使用固定大小的数组那样使元素未定义

该标准是否对此有任何说明,或者编译器是否可以自由地“猜测”,例如,如果我设置
A(23)=42
,那么所有元素
A(1:22)
都可以不定义(或NaN,或垃圾

注意:当我说“保留它们的初始值”时,我指的是子例程之外的实际参数中的值。子例程本身并不关心这些元素的值,它从不读取或写入它们。

从伪参数的角度看“变得未定义”意味着什么。但是,与伪参数相关联的实际参数也适用于相同的方面:它变得未定义

Fortran标准本身就“保留”未触及的值这一方面给出了说明(Fortran 2018,8.5.10,注4):

INTENT(OUT)表示调用过程后参数的值完全是执行该过程的结果。如果一个参数可能没有被重新定义,并且在这种情况下希望该参数保留其值,则不能使用INTENT(OUT),因为它会导致该参数变得未定义

进一步考虑,当程序不关心值:

时,<代码>意图(IOUT)< /代码>是否合适? 但是,即使没有对伪参数值的显式引用,也可以使用INTENT(INOUT)

假定数组的大小在实际参数和伪参数的未定义中不起作用。再次强调一下,我对另一个问题的回答:“未定义”并不意味着值发生了变化。由于编译器没有需要执行的取消定义值的操作,因此它不需要计算出要取消定义的值:使用假定的size伪参数,过程不知道它有多大,但这并不能免除编译器“取消定义”它,因为没有什么可原谅的

您可能会看到,假定大小数组的“未定义”部分保持完全相同,但
intent(inout)
(或没有指定的intent)仍然是兼容Fortran程序的正确选择。例如,使用带有
intent(out)
的copy-in/copy-out机制,编译器不必确保定义了副本,也不必将垃圾复制回来


最后,是的,编译器(可能是希望成为一个好的调试编译器)可能会更改未定义的值。如果该过程引用数组的第n个元素,则允许假定它前面有n-1个元素,并根据它的选择对它们进行设置,用于
intent(out)
dummy,而不是
intent(inout)
dummy。(如果您访问
A(n)
,则允许编译器假设该元素以及声明的下限中的所有元素都存在。)

未定义的值与编译器设置为NaN(或其他值)无关,但您作为程序员可以依赖的是什么。如果需要“初始值”,那么即使编译器实际上不会“重置”这些值,也不能使用
intent(out)
。这是Fortran指定的,而不是您可以“侥幸逃脱”的。(链接中有更多详细信息,但如果这对您的问题没有帮助,我们可以重新评估副本。)@francescalus我明白,如果我使用
intent(out)
,我不能依赖子程序中的这些“初始值”。我的问题是关于子例程之外的实际参数值会发生什么变化。我在问题上加了一个“便条”,希望这就足够了?我认为这个问题是关于不同的东西。传递的值没有任何关系。问题是关于数组的其余部分。如果我将10个元素的数组传递给
维度(*),intent(out)
参数,其中子例程只访问5个元素,那么其他5个元素会发生什么情况?如果arg是
维度(5),intent(out)
并且我传递了一个10元素数组,该怎么办?@VladimirF这确实是一种可能的情况。如果
A
被定义为
dimension(10)
,那么我将
A(2)
传递给一个具有
dimension(*),intent(out)::foo
,并且只执行
foo(3)=0
foo(3)
A(4)
,它变为零。是否允许编译器更改
a(2:3)
的值?通过哪种方法可以
A(5:10)
变得未定义?@Jellby,实际参数和伪参数在进入过程时都未定义。如果在此示例中仅定义
A(4)
,而不定义
A(2)
A(3)
A(5)
等,则一旦过程完成,这些其他值将保持未定义状态。如果你能再解释一点,为什么你不清楚,我会在回答中提到。(是的,
A(1)
保留定义,因为这不是实际参数的一部分。)@VladimirF,如果实际参数是10个元素,那么这10个元素