簡體   English   中英

如何在 fortran 編譯器中指定聲明的變量不應被視為隱式函數聲明

[英]How can I specify in fortran compiler that declared variables shoud not be potentially treated as implicit function declaration

我很驚訝:

      subroutine test   (es, f)
!

      implicit none
!
      double precision es
      double precision f
      f=es(1,2)
!
      return
      end

編譯時沒有任何錯誤或警告: es未用dimension聲明。
我知道es然后被認為是一個函數。

但是在鏈接時考慮到缺少符號es沒有錯誤!

查看匯編程序es(1,2)對應於call rdx ,因此沒有鏈接錯誤。

為了避免這個問題,我可以將es聲明為double precision, intent(inout)然后我得到:

錯誤:PROCEDURE 屬性與“es”中的 INTENT 屬性沖突

這是我第一次期待的。

是否有編譯器選項(ifort 或 gfortran)來強制將聲明的變量視為intent(inout)而不是procedure call

先感謝您。

Ps:我有一個遺留代碼,我不想在任何地方添加intent(inout)來檢測這種誤解。

“但是在鏈接時考慮到缺少符號 es 沒有錯誤!”

不應該有一個。 es是虛擬參數的名稱,而不是您將在那里傳遞的實際過程的名稱。 在大多數實現中實際會發生什么,代碼會嘗試將指向變量的指針作為函數地址調用,這會導致某種錯誤。 要么執行不可執行的代碼,要么執行無效指令,要么執行被入侵者小心放置到堆棧或堆正確位置的病毒代碼。

“是否有編譯器選項(ifort 或 gfortran)來強制將聲明的變量視為意圖(輸入輸出)而不是過程調用?”

不,即使是這樣,它也會破壞代碼語義,這是一件壞事(TM)。 任何在其他地方使用代碼或沒有選項的人都會被搞砸。 特別是它創建了一個可能的危險代碼漏洞這一點是不允許這種事情發生的明確理由。


最好明確地說,即使我相信您已經意識到這一點並且只是想要一個診斷工具來警告您:

數組的正確聲明涉及其維度,例如

double precision es(1,*)

還要注意,編譯器能夠在調用過程時檢查類似的錯誤。 Gfortran 會找出調用代碼何時在同一個文件中,英特爾有時即使不是(啟用-warn interfaces時)。 啟用鏈接時間優化也可能有助於找到它。 當然,現代 Fortran 應該使用模塊。

考慮:

      subroutine test   (es, f)
!

      implicit none
!
      double precision es
      double precision f
      f=es(1,2)
!
      return
      end

   double precision a(2,1), b   
   call test(a, b)
end

由於調用在同一個文件中,gfortran 會自動識別問題,無需任何附加選項:

declaration.f90:14:13:

    call test(a, b)
             1
Warning: Rank mismatch in argument ‘es’ at (1) (scalar and rank-2) [-Wargument-mismatch]

英特爾將需要警告標志

ifort -warn interfaces declaration.f90 
declaration.f90(14): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function.   [A]
   call test(a, b)
-------------^
compilation aborted for declaration.f90 (code 1)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM