2011-08-15 14 views
2

在FORTRAN可以聲明與任何合適的(積分)的範圍的陣列,例如:負陣列索引和放置在存儲器(定點)

real* 8 array(-10:10) 

相信FORTRAN,通過引用傳遞時,始終將傳遞數組(1)作爲參考,但我不確定。我使用的是Fortran指針,我相信Fortran指向「1st」元素地址,即數組(1),而不是數組(-10)。但我不確定。

Fortran如何處理內存中負數組索引?它是否有助於定義?

編輯:爲了增加更多的細節,我通過使用fortran指針指向地址,通過從內部調用fortran例程完成,將C的malloc'd塊傳遞給fortran CIE Ç雲:

void * pointer = malloc(blockSize*sizeof(double)); 
fortranpoint_(pointer); 

而且FORTRAN點例行的樣子:

real*8 :: target block(5, -6:6, 0:0) 
real*8 :: pointer array(:,:,:) 

entry fortranPoint(block) 
array => block 
return 

的問題是,有時當它後來試圖訪問說:

array(1, -6, 0) 

我不知道,如果這是訪問該塊的開始或之前的地址。我現在認爲這是實現定義的,但想知道每個實現的細節。

回答

1

Fortran數組參數ABI取決於編譯器,也許更重要的是,調用的過程是否具有顯式或隱式接口。

對於隱式接口,通常會傳遞第一個元素的地址[1]。在被調用者中,程序然後根據聲明數組僞參數的方式添加一個偏移量。例如。如果陣列僞參數被聲明的someArray(-10:10),然後一個參考的someArray(x)被計算爲

address_of_first_element_passed_in_to_the_procedure + x + 10 

如果過程具有顯式接口,典型的陣列描述符結構被傳遞,而不是第一個元素的地址。在這種結構中,被調用者可以找到關於每個維度的邊界的信息,當然還有一個指向實際數據的指針,允許它計算正確的偏移量,類似於隱式接口的情況。

[1]請注意,這是內存中的第一個元素,也就是每個維度的最低索引。不管數組是如何聲明的,都不是數組(1)。

要解答更新的問題,對於C/Fortran互操作性,請使用現在廣泛使用的ISO_C_BINDING功能。這提供了一種在C和Fortran之間傳遞信息的標準化方法。

+0

使用ISO_C_BINDING是否需要我更改Fortran中使用的數據類型?我簡單地看了一下,我無法分辨。我是一名C程序員,不得不與一些Fortran一起工​​作,我無法像改變數據類型那樣大規模地編輯它。 – VolatileStorm

+0

那麼,你需要確保類型和種類相匹配,是的。但我不認爲這是一個特別大的問題。例如。如果C代碼使用雙精度,那麼ISO_C_BINDING的東西應該使用REAL(kind = C_DOUBLE),然後您需要確保REAL(kind = C_DOUBLE)與您綁定的Fortran過程使用的類型相同。請注意,種類只是整數參數;在今天的大多數編譯器上,KIND(1.0d0)== C_DOUBLE == selected_real_kind(15)== 8,所以很有可能你很好走。 – janneb

+0

ISO_C_BINDING在我的一個目標平臺上不存在,所以我不能編寫涉及它的代碼,很不幸。你有什麼想法在哪裏我可以找到詳細的信息,哪些編譯器做什麼數組?與此同時,我還沒有聽說過「隱式」和「顯式」接口。他們的意思是什麼? 謝謝! – VolatileStorm

0

如果Fortran中常規數組的僞參數聲明爲A(:)(或更多維),則會傳遞SHAPE,而不是特定的索引範圍。所以該過程將默認爲單索引。您可以用A(-10 :)或A(StartIndex :)的過程中的聲明覆蓋此,其中StartIndex是另一個參數。

Fortran指針確實包含索引範圍,但傳遞機制將依賴於編譯器。將此接口連接到C的代碼很可能是編譯器所依賴的OS &。正如已經建議的那樣,我會使用常規數組和ISO C綁定。這比找出編譯器傳遞機制以及標準和便攜式的舊方法要容易得多。如果您有大量現有的Fortran代碼,則可以編寫一個「粘合」Fortran過程,該過程在常規Fortran變量聲明和ISO C綁定名稱之間進行映射。雖然它們的類型會有正式的不同名稱,但實際上,如果您選擇正確的ISO C類型,它們將是相同的。 ISO C綁定已經可以使用很多年了 - 您是否可以在問題目標平臺上升級編譯器?如果沒有,我會使用一個普通的Fortran數組,並在C端使用零索引,或者顯式傳遞期望索引的參數。

在其他堆棧溢出問題上有ISO C綁定使用的例子。

如果過程的接口已聲明,以便調用程序中的編譯器知道,則過程的接口是顯式的。將過程放置在模塊中並在呼叫者中「使用」模塊的最簡單方法。具有顯式接口有助於避免錯誤,因爲編譯器可以檢查調用者和被調用者參數之間的一致性。它有點像C頭文件,只是更容易。