32 비트 시스템에서 작동하는 C 호출로 약간 오래된 Fortran 프로그램을 살펴 보았지만 64 비트 컴파일러에서 경고 및 문제가 발생합니다. 이 프로그램은 동적으로 할당 된 메모리에 대한 C 포인터의 주소를 int
으로 저장하며 포트란 측에서는 INTEGER
으로 공유됩니다. 내 관심은 64 비트 정수 시스템에서 C 포인터의 캐스트가 int
/INTEGER
으로 저장할 수있는 것보다 클 수 있다는 것입니다. 두 파일을 사용하여 기존 프로그램을이 예제로 단순화했습니다.Fortran/C 프로그램을 32 비트에서 다중 아키텍처로 업그레이드
포트란 : this.f
program this
integer,pointer :: iptr
allocate(iptr)
call that_allocate(iptr)
write(*,'(A, Z12)') 'Fortran: iptr address', iptr
call that_assemble(iptr)
call that_free(iptr)
end program this
C : that.c
#include <stdlib.h>
#include <stdio.h>
typedef struct data {
int a;
float b;
} data;
void that_allocate_(int* iptr)
{
data *pData = calloc(1, sizeof(data));
*iptr = (int)pData;
printf("C: Allocated address %p (or %d)\n", pData, pData);
return;
}
void that_assemble_(int* iptr)
{
data *pData = (data *) *iptr;
pData->a = 42;
pData->b = 3.1415926;
return;
}
void that_free_(int* iptr)
{
data *pData = (data *) *iptr;
printf("C: Freeing data %d and %g at %p\n", pData->a, pData->b, pData);
free(pData);
return;
}
컴파일
프로그램은 32 비트-m32
와 GNU 컴파일러로 컴파일 될 수
(아무 문제 여기) 64 비트의 경우 -m64
C 코드를 컴파일하면 몇 가지 경고를 제기
$ gcc -m64 -c that.c
that.c: In function ‘that_allocate_’:
that.c:12: warning: cast from pointer to integer of different size
that.c: In function ‘that_assemble_’:
that.c:19: warning: cast to pointer from integer of different size
that.c: In function ‘that_free_’:
that.c:27: warning: cast to pointer from integer of different size
나머지 컴파일 및 링크 괜찮하면서, 프로그램 작동 :
$ gfortran -m64 -o prog this.f that.o
$ ./prog
C: Allocated address 0x1130b40 (or 18025280)
Fortran: iptr address 1130B40
C: Freeing data 42 and 3.14159 at 0x1130b40
질문
내가 볼 수 있지만 calloc
할 수있는 주소를 반환 4 바이트 정수의 데이터 한계에 맞으면, 더 큰 정수로 주소를 반환하는 calloc
의 위험이 있습니까? (intptr_t)
으로 캐스팅하면 컴파일 경고가 사라지지만 포인터가 잘린 주소로 캐스팅하려고하면 "세그멘테이션 오류"와 상위 비트는 자릅니다. 이 올바른지?
어떻게해야합니까? 수정 프로그램이 포트란 코드를 사용해야합니까?
덕분에, 그 좋은 예입니다! ISO_C_BINDING이 앞으로 나아갈 길입니다. –