C++ 语言中的 FORTRAN EQUIVALENCE

FORTRAN EQUIVALENCE in C++ language

我正在将一部分 FORTRAN 77 代码转换为 C++

DIMENSION ARRAY(513),JRRAY(2,513)
EQUIVALENCE (ARRAY(1),JRRAY(1,1))

这是隐式代码,其中每个以I,J,K,L,M,N,O,P开头的变量名都隐式地作为整数类型。因此,这里我们有一个名为 ARRAY 的双精度数组和一个名为 JRRAY 的整数数组。

等价语句将两个数组的开头指向相同的内存位置。然而,不知何故,当调用 ARRAY(I) 时,字节被解释为双精度,而当调用 JRRAY(I,J) 时,字节被解释为整数(至少我认为会发生这种情况)。

在 C++ 中是否有类似的方法可以将相同的内存位置解释为不同的类型?

或者与 FORTRAN 中的 EQUIVALENCE 相同的东西,但在 C++ 中。

类似的特征是 union:

union {
    double array[513];
    int jrray[513][2];
} equiv;

然后您可以访问 equiv.array[i]equiv.jrray[i][j]

但是请注意,访问与上次写入的联合成员不同的联合成员会导致 C++ 中的未定义行为。参见 Unions and type-punning。如果你想将数据重新解释为不同的数据类型,你应该使用 reinterpret_cast<>,而不是类型双关。

C union 通常用于此目的,如 Barmar 的 。然而,您可以使用类型转换将浮点数组引用为整数数组。

考虑以下 array 的声明和 jrray 的定义:

double array[513];
int (*jrray)[2] = reinterpret_cast<int (*)[2]>(array);

我们可以通过查看指数来检查此声明是否按预期工作。我们将在 jrray[k][1].

的第 20-30 位中得到 array[k] 的指数

例如,检查我们现在是否将数组元素初始化为

array[0] = 1.23*2; // exponent is 1
array[1] = 1.23*4; // exponent is 2
array[2] = 1.23*8; // exponent is 3

我们会有

((jrray[0][1] >> 20) & 0x7FF) - 1023 == 1
((jrray[1][1] >> 20) & 0x7FF) - 1023 == 2
((jrray[2][1] >> 20) & 0x7FF) - 1023 == 3

无论哪种方式,这都违反了 C++ 严格的别名规则,并可能导致未定义的行为。