常見塊

在 Fortran 的早期形式中,從子例程和函式可見的唯一建立全域性變數儲存的機制是使用 COMMON 塊機制。這允許變數序列成為名稱並共享共享。

除了命名的公共塊之外,還可能存在空白(未命名)公共塊。

可以宣告一個空白的公共塊

common i, j

而命名塊 variables 可以宣告為

common /variables/ i, j

作為一個完整的例子,我們可以想象一個可以新增和刪除值的例程使用的堆儲存:

       PROGRAM STACKING
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       ICOUNT = 0
       READ *, IVAL
       CALL PUSH(IVAL)
       CALL POP(IVAL)
       END

       SUBROUTINE PUSH(IVAL)
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       ICOUNT = ICOUNT + 1
       ISTACK(ICOUNT) = IVAL
       RETURN
       END

       SUBROUTINE POP(IVAL)
       COMMON /HEAP/ ICOUNT, ISTACK(1023)
       IVAL = ISTACK(ICOUNT)
       ICOUNT = ICOUNT - 1
       RETURN
       END

通用語句可用於隱式宣告變數的型別並指定 dimension 屬性。僅此行為通常是混淆的充分來源。此外,隱含的儲存關聯和跨程式單元的重複定義的要求使得使用公共塊容易出錯。

最後,公共塊在它們包含的物件中非常受限制。例如,公共塊中的陣列必須具有顯式大小; 可分配的物件可能不會發生; 派生型別不得具有預設初始化。

在現代 Fortran 中,這些變數的共享可以通過使用模組來處理。上面的例子可以寫成:

module heap
  implicit none
  ! In Fortran 2008 all module variables are implicitly saved
  integer, save::count = 0
  integer, save::stack(1023)
end module heap

program stacking
  implicit none
  integer val
  read *, val
  call push(val)
  call pop(val)

contains
  subroutine push(val)
    use heap, only : count, stack
    integer val
    count = count + 1
    stack(count) = val
  end subroutine push

  subroutine pop(val)
    use heap, only : count, stack
    integer val
    val = stack(count)
    count = count - 1
  end subroutine pop
end program stacking

命名空白公共塊的行為略有不同。值得注意的是

  • 最初可以定義命名公共塊中的物件; 空白常見的物體不得
  • 空白公共塊中的物件表現得好像公共塊具有 save 屬性; 當塊不在活動程式單元的範圍內時,沒有 save 屬性的命名公共塊中的物件可能變為未定義

後一點可以與現代程式碼中模組變數的行為形成對比。Fortran 2008 中的所有模組變數都是隱式儲存的,當模組超出範圍時不會變為未定義。在 Fortran 2008 模組變數(如命名公共塊中的變數)之前,當模組超出範圍時,它們也將變為未定義。