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) ::
如果我在 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) ::