C_INT fortran 类型需要什么? C 和 Fortran 整数有如此不同吗?

What is the need for a C_INT fortran type? Are C and Fortran integers so different?

如果我在 fortran 中声明一个整数为: INTEGER(C_INT) :: i 那么,如果我没理解错的话,传递给C函数是安全的。现在忽略总是以这种方式声明整数的额外麻烦,有什么理由不总是将你的变量声明为 C 互操作的?这样做有什么缺点吗?

此外,对于像整数这样简单的东西,C_INT 与传统的 Fortran 整数相比到底有何不同? Fortran 和 C 整数实际上不同吗?

C 整数大小通常是固定的,因为 OS 是使用 C 编译的,系统绑定发布为 C headers。操作系统设计者选择一种常见模型,如 LLP64, LP64, ILP64(对于 64 位指针 OS),然后 C 编译器遵循此选择。

但是 Fortran 编译器更加自由。您可以将它们设置为不同的配置。设置为使用 8 字节默认整数和 8 字节默认实数的 Fortran 编译器仍然完全符合标准! (C 也可以,但选择在操作系统中是固定的。)

并且因为 C 和 Fortran 中的整数不必匹配,所以您需要一种机制 可移植 select C 可互操作的类型,无论默认类型是什么.

这不仅仅是学术上的。你可以找到像 MKL 这样用 8 字节整数编译的库(ILP64 模型,C 的常见操作系统不使用它)。

所以当你调用一些API,一些接口在C中定义的函数时,你想正确地调用它,而不是依赖于Fortran编译器的设置。这就是 C-interoperable 类型的用例。如果 C 函数需要一个 int,你给它一个 integer(c_int) 并且你不关心 Fortran 默认整数是否相同。

基本上没有根本的缺点,在同一个编译器上也没有根本的好处。

即使在 icc 中,long int 在 32 位和 64 位上也是不同的 OS,因此您需要知道(或在事物的 c 端定义您想要的)。

唯一明显是 4 字节的是 C_INT32_T,因此它是我通常使用的那个。而且它更多的是 "future proofing" 努力使用 C_INT32_T ,将它定义为您希望它处于固定位数的大小。

这些都给出了 iFort 上的 4 字节整数。

USE ISO_C_BINDING, ONLY : C_INT, C_INT32_T
Integer                 :: 
INTEGER(KIND=4)         ::   !"B"  At least on iFort
INTEGER*4                    !"A"  
INTEGER(KIND=C_INT)     ::
INTEGER(KIND=C_INT32_T) ::   !"C"

通常会发现具有 "A" 风格的旧代码。

我经常使用"B"的样式,但尽管这是"defacto standard",但它不符合"the standard"。

然后,当我开始关注可移植性时,我 运行-通过并将 "B" 样式更改为 "C" 样式,然后考虑到其他人可能会在以后编译gfortran 编译器...甚至其他编译器。

单字节:

BYTE                        :: !Good
INTEGER(KIND=1)             ::
INTEGER(KIND=C_SIGNED_CHAR) ::
INTEGER(KIND=C_INT8_T)      :: !Best

两个字节:

INTEGER(KIND=2)            ::
INTEGER(KIND=C_INT16_T)    :: !Best
INTEGER(KIND=C_SHORT)      ::

8字节:

INTEGER(KIND=8)            ::
INTEGER(KIND=C_INT64_T)    :: !Best
INTEGER(KIND=C_LONG_LONG)  ::

虽然这看起来有点可疑......也可以说:

LOGICAL(KIND=4)         ::
LOGICAL(KIND=C_INT32_T) :: !Best here may be C_bool and using 1-byte logical in fortran...? Assuming that there is no benefit with the size of the logical being the same as some float vector
LOGICAL(KIND=C_FLOAT)   ::