长C整数的Fortran互操作性



我有一个C库,它在结构中声明了几个long变量。在Fortran中,我通常将它们视为integer(kind=c_long),但这在特定的更复杂的程序中会导致意想不到的问题。我的Fortran代码在32位系统中可以正常运行,在64位系统中甚至无法编译。原因太复杂了,无法在这里解释,对于问题的目的来说,这并不重要,但归根结底,c_long在32位和64位系统中是不一样的。至少在gfortran中,c_long在32位中是4字节,在64位中是8字节。事实上,c_long = c_int = 4是32位的,而c_long = c_double = 8是64位的。

现在,在这个特定的C库中,long整数只用于char变量,使用的最大值是$FFFFFF,远远超出了32位系统中c_long整数的限制,因为huge(1_c_long)=$7FFFFFFF是32位系统。所以我有几种方法来摆脱这个问题,但我仍然想知道……为什么要以这种方式出现呢?例如,c_double在32位和64位系统中都是相同的(应该如此);同样的c_int,它是相同的,无论什么。为什么c_long是不同的?我花了好几个小时才弄清楚一个复杂的程序是怎么回事。

long(甚至int)没有统一的长度。各种系统和编译器使用一种通用的数据模型(维基百科),int,long,long long和指针使用32位或64位。

Fortran使用伴随处理器的概念指定iso_c_binding类型。. 这意味着Fortran编译器在其特定配置(在特定操作系统中)中使用这些类型来与特定操作系统中具有某些特定配置的特定C编译器兼容。

值得注意的是,Microsoft Windows上的Microsoft和MinGW C编译器使用LLP64模型。Linux和其他unix上的编译器通常使用LP64数据模型。因此,long的大小不同。

如果没有具体的细节(编译器,操作系统),很难对您的情况说更多。但是这些大小不是通用的,只对特定操作系统上的特定编译器有效,Fortran编译器将其视为配套处理器

下面的小程序揭示了正在发生的事情:

#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(或其他任何东西)。

相关内容

  • 没有找到相关文章

最新更新