Fortran。下面显示的哪个代码是正确的?

时间:2019-07-08 17:48:18

标签: fortran

我发现了Fortran中的下一个有趣的事情。如下面的代码示例所示。

我不明白,也没发现为什么标签10和12上的代码可以正常工作,而标签11和13上的代码不能正常工作。

implicit none
integer     :: i
integer     :: IA(8) = [(i, i=1,8)]
integer     :: IP

IP = 5
10  IA(IP:2) = [11, 12]     ! works
11  IA(5:2) = [11, 12]      ! doesn't work
12  print *, IA(IP:IP+1)    ! works 
13  print *, IA(IP:2)       ! doesn't work

有什么区别?

1 个答案:

答案 0 :(得分:1)

标记为1011的语句的两个版本都是错误的。

数组部分ia(5:2)是由数组ia的零个元素组成的数组部分。数组节ia(IP:2)(当IP是值为5的变量时)是相同的。

在数组元素下标中使用文字常量时,编译器在编译时会知道可以检查左侧和右侧形状的匹配。您的编译器在这里确定ia(5:2)的形状为[0],而[11, 12]的形状为不可整合[2]。因此,它将报告错误。

您的编译器在编译时未检测到ia(IP:2)中带有非恒定下标的错误。但是,该代码以完全相同的方式违反了Fortran标准。您看到的看似正确的输出是不好运气。

由于您曾经使用的编译选项,或者由于编译器未(正确)应用形状测试,因此您的编译器可能在运行时未检测到错误。

其他编译器可能会抱怨,例如以下消息:

Rank 1 of constant array operand has extent 2 instead of 0
Program terminated by fatal error
Abort (core dumped)

带有声明

print *, IA(IP:2)

这可以“工作”(在其他正确形成的程序中)。但是,它遭受的误解与以前完全一样。

与两个元素ia相比,此print语句打印出ia(5:6)的零个数组元素。而不是“不工作”,缺少明显的输出是正确地不打印任何内容/空白行。

最后,ia(5:2)不是对ia(5)之后的两个元素的引用。为此,您需要ia(5:6)ia(ip:ip+1)。下标都是界限,不是界限和计数。