2017-05-23 5 views
2

에서 I가 FORTRAN 77 코드의 일부를 변환하고 C++FORTRAN 동등한 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)가 호출 될 때 double 또는 JRRAY (I, J)가 호출 될 때 정수로 해석됩니다 (적어도 그것이 어떻게되는지 생각합니다).

동일한 메모리 위치를 다른 유형으로 해석 할 수있는 C++과 비슷한 방법이 있습니까?

또는 FORTRAN의 EQUIVALENCE와 동일하지만 C++의 경우와 동일합니다.

+1

포트란 배열은 열 순서대로 저장되므로'JRRAY (1, X)'와'JRRAY (2, X)'는'ARRAY (X)'의 연속 부분을 가리킨다는 것을 상기하십시오. –

+0

표현의 실제 재 해석 또는 자동 변환을 의미합니까? 나는. 파이를'ARRAY'에 저장하고'JRRAY '에서 읽을 수 있다면'double'의 비트 패턴에 해당하는'3' 또는 숫자를 얻을 수 있을까요? – Quentin

+0

@Quentin FORTRAN은 단순히 표현을 재 해석하므로 C++에서 수행하려는 것으로 추정됩니다. – Barmar

답변

5

유사한 기능은 union입니다 :

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

당신은 다음 equiv.array[i] 또는 equiv.jrray[i][j]에 액세스 할 수 있습니다.

그러나 마지막으로 작성한 유니언의 다른 구성원에 액세스하면 C++에서 정의되지 않은 동작이 발생합니다. Unions and type-punning을 참조하십시오. 데이터를 다른 데이터 형식으로 다시 해석하려면 자르기를 입력하지 말고 reinterpret_cast<>을 사용해야합니다.

+0

리콜 FORTRAN은 컬럼 메이저이기 때문에 jrray의 치수를 바꿔야합니다. –

+0

이것은 UB이므로 구현이 실제로이를 지원하는지 확인해야합니다. – Quentin

+2

@Quentin 마지막으로 쓴 회원이 아닌 다른 회원에게 접속하면 UB 만 가능합니다. 유니온 자체가 지원됩니다. 나는 C와 C++에서 타입 펀닝의 문제를 설명하는 또 다른 질문에 대한 링크를 추가했다. – Barmar

1

B에서처럼 C 이 종종이 용도로 사용됩니다. 그러나 부동 소수점 배열을 정수 배열로 참조하기 위해 타입 변환을 사용할 수 있습니다.

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

우리는 지수를 보면, 예를 들어 예상대로이 선언 작동하는지 확인할 수 있습니다

jrray의 다음 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 

로 배열의 요소를 초기화하면 우리가이 C++ 엄격한 앨리어싱 규칙을 위반

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

하나의 방법이되고 정의되지 않은 동작이 발생할 수 있는지 확인합니다.

+2

주의 : 위의 union 트릭과 마찬가지로 정의되지는 않지만, 구현과는 달리 일반적으로 구현에 의해 정의되지 않으며 약간의 교란 상태에서 중단됩니다. 예제는 [here] (https://godbolt.org/g/2EUDU7)를 참조하십시오. – Quentin

+0

@Quentin OP가 FORTRAN 코드를 이식하기 때문에 함수 인수가 별칭이 아니어도 안전 할 수 있습니다. –

+0

이것은 단지 예입니다. 컴파일러는 더 많은 최적화 (함수를 인라인 할 때 여기에서와 같이)를 할 수 있다면 이것이 두 개의 별개의 배열이라고 행복하게 추측 할 것입니다. 당신은 단지 그것에 의존 할 수 없습니다. – Quentin