我有一個 C 庫,它long在結構中宣告了幾個變數。我通常像integer(kind=c_long)在 Fortran 中一樣對待它們,但這會在特定的更復雜的程式中引起意外問題。我的 Fortran 代碼在 32 位系統中運行正常,在 64 位系統中甚至無法編譯。原因太復雜了,無法在這里解釋,對于問題的目的來說并不重要,但歸結為c_long在 32 位和 64 位系統中不一樣的事實。至少在 gfortran 中,c_long32 位是 4 個位元組,64 位是 8 個位元組。實際上,c_long = c_int = 4在 32 位中,而在 64 位中是c_long = c_double = 8.
現在,在這個特定的 C 庫中,long整數僅用于char變數,并且使用的最大整數是 $FFFFFF,遠遠超出了c_long32 位系統中整數的限制,因為huge(1_c_long)=$7FFFFFFF在 32位系統中。所以我有幾種方法可以解決這個問題,但我仍然想知道......為什么首先必須這樣?例如,c_double在 32 位和 64 位系統中都相同(應該如此);相同 for c_int,無論如何都是相同的。為什么c_long不同?正因為如此,我花了幾個小時才弄清楚復雜程式中發生了什么。
uj5u.com熱心網友回復:
沒有long(或什至int)的通用長度。各種系統和編譯器使用公共資料模型(之一維基百科),其使用任一32位和64位int,long,long long和指標。
Fortraniso_c_binding使用配套處理器的概念來指定型別。這意味著 Fortran 編譯器在其特定配置(在特定作業系統中)使用的型別與特定 C 編譯器與特定作業系統上的某些特定配置兼容。
值得注意的是,Microsoft Windows 上的 Microsoft 和 MinGW C 編譯器使用 LLP64 模型。Linux 和其他 Unix 上的編譯器通常使用 LP64 資料模型。因此大小long不同。
如果沒有具體的細節(編譯器、作業系統),很難為您的情況多說什么。但是這些大小不是通用的,僅對 Fortran 編譯器視為配套處理器的特定作業系統上的特定編譯器有效。
uj5u.com熱心網友回復:
下面的小程式揭示了發生了什么:
#include <limits.h>
#include <stdio.h>
int main() {
printf(" Maximum int: %X (%u bytes)\n",INT_MAX,sizeof(int));
printf("Maximum long: %lX (%u bytes)\n",LONG_MAX,sizeof(long));
return 0;
}
在 32 位 GNU/Linux 系統上使用 gcc 11.2 這給出:
Maximum int: 7FFFFFFF (4 bytes)
Maximum long: 7FFFFFFF (4 bytes)
在 64 位系統上,它提供:
Maximum int: 7FFFFFFF (4 bytes)
Maximum long: 7FFFFFFFFFFFFFFF (8 bytes)
因此,Fortran 沒有做錯任何事。問題(或者不管人們如何稱呼它)來自 C 方。沒有標準——或者至少沒有一個標準——并且 C 沒有類似于 Fortran 的固定大小型別的東西(這并不完美,但至少讓事情變得不那么令人困惑)。long整數在 C 中是不同的,這取決于您的作業系統。所以iso_c_binding別無選擇,只能提供不同的c_long型別。
經驗教訓:永遠不要假設任何事情。不存在單一的、通用的,c_long而且正如 Vladimir F 指出的那樣,也不存在單一的通用c_int(或其他任何東西)這樣的東西。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/341602.html
標籤:C 复式 互操作 Fortran-iso-c-结合
上一篇:陣列中的數字大于其右側數字的總和
