现代Fortran中数组的连续性

4
我正在阅读《现代Fortran解释》(2018年版)。在第24页上写道:
大多数实现实际上以数组元素顺序在连续的存储器中存储数组,但我们强调标准并没有要求这样做。
我相信这已经追溯到老的Fortran 77(甚至更早)了。给定声明:
real, dimension(5,5) :: a

我理解的是,标准不要求此数组是连续的。这与本书第7.18.1节第140页上所说的一致:
“......Fortran标准避免规定数组是否在占据连续内存位置且没有中间未占用的空间。”
但随后该书(仍在p140)继续写道:
“以下任何数组都被认为是标准的连续数组之一:”
  • 一个带有连续属性的数组;
  • 一个整个数组(命名数组或没有进一步限定的数组组件),它不是指针或假设形状;
  • ...
    我理解第一个标准;但是第二个标准让我感到困惑。这是否与早期的 Fortran 标准不需要按数组元素顺序将数组存储在连续存储器中相矛盾?现代 Fortran 是否已经摒弃了这种范例?还是以上引文之间并不互相矛盾,因为存在我对这个主题的理解之外的其他原因?在上述示例中,数组 a 是否需要是连续的?

  • 1
    有些数组不是(必须)连续的,例如指针数组或假定形状数组。第二个语句的意思是这样的,这并不矛盾。所以我们可以更好地解释,你能详细说明哪些部分你不理解吗?(Fortran 77 没有这两者之一。) - francescalus
    2个回答

    5

    语言标准规定了以标准描述的概念为基础所必须发生的事情(按照特定顺序执行语句、使用具有值的变量、将内容写入称为“文件”的东西),但它没有说明这些事情如何发生/如何实现。

    可能存在一种明显的实现方法,甚至只有一种实用的方法,但是标准并未指定实现方式。

    标准甚至不要求“Fortran处理器”是一种电子设备。

    实际上,“连续数组”(Fortran标准语言术语)通常会通过在RAM中相邻存储表示数组元素值的字节来实现,但这是实现细节,而不是语言标准要求。

    对于程序员来说,意识到可能的实现方法通常很方便,特别是在调试或理解性能方面,但实现和规范不应混淆。


    3

    这里存在两个不同的连续性概念。

    在Fortran语言中,连续性的意思为(Fortran 2018, 3.41):

    数组元素按顺序排列且未被其他数据对象隔开

    如果数组在内存中存储时存在填充空间,这种连续性的概念允许在数组元素之间添加填充。连续性的含义是A(1)A(2)之间没有对象。

    也就是说,一个标量可能会占用一些空间,但作为数组元素,同一个对象可能会占用更多的空间。正如(F2018 16.9.184,注1)所述:

    数组元素的存储位数可能比独立标量变量要多,因为阵列元素的任何硬件强制对齐要求可能不适用于简单标量变量。

    关于哪些数组被认为是连续的描述是指这种连续性概念。第二个引文中提到的另一种连续性概念并非强制执行。

    根据您的示例:

    real, dimension(5,5) :: a
    

    我们确实有一个连续的数组 a: 它是一个完整的数组,不是指针,也不是假定形状。它仍然可能在元素之间存在一些填充程度。


    谢谢!总结您的回复是否公平,即p140讨论了两个不同的连续性概念。第一个是指“占用连续的内存位置,没有中间的未占用空间”。第二个是指有介于已占用空间的数组元素。前者未被标准规定;后者被排除在外。正确吗? - Twirl
    可以想象一个派生类型 type t; integer i; character c; end type。编译器可以自由地实现一个数组 type(t) c(2),其内存布局为 iiiic...iiiic...iiiiciiiic(例如,对于整数、字符和填充 (.) 存储),或其他几种方式之一。 - francescalus

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接