2012-12-04 3 views
0

정확히 32 비트 Linux 시스템이 64 비트 Linux와 비교하여 long long int을 처리합니까?32 비트 Linux와 64 비트 Linux 및 MPFR에서 긴 long int

내 32 비트 시스템에서는 MPFR 데이터 유형에 C++ wrapper을 사용합니다. 이 래퍼에는 long int에 대해 정의 된 생성자가 있지만 long long int에는 정의되지 않았습니다. 그럼에도 불구하고 32 비트 시스템에서이 코드는 작동합니다.

long long int i=5LL; 
mpreal myVar(i); 
cout<< "this was constructed with a long long int:" <<myVar <<endl; 

어떻게 가능합니까? 32 비트 gcc가 long long int을 데이터 유형 에 으로 전송하면 생성자를 가지고 있습니까?에 생성자가 있습니까? 위의 코드가 64 비트 Linux에서 실행되면 컴파일러는 구성이 모호하다는 오류를 발생시킵니다.

나는 어떤 사람들은 64 비트에서 전혀 long long int을 사용하지 말라고 말할 것임을 알고 있지만 불행히도이 코드는 다중 정밀도 데이터 형식을 구성하기 위해 빌드 된 다른 라이브러리 (odeint)를 사용하고 있습니다. 나는 변화시킬 수 있다고 생각하지 않습니다.

long long int은 어쨌든 long int과 동일합니까? long int으로 전송하면 데이터가 손실됩니까? 예 : 내가 좋아하는 내 자신의 생성자를 만들 경우 : 다양한 유형의 크기

mpreal(const long long int u, mp_prec_t prec, mp_rnd_t mode) 
{ 
    mpfr_init2(mp,prec); 
    mpfr_set_si(mp, u, mode); 
} 
+0

모호한 생성자는 무엇입니까? – ecatmur

+0

'오류 : 오버로드 된 'mpreal (long long int)'의 호출이 모호합니다. ''long long int ''에 의해 생성되는 것으로 정의되지는 않았지만 32 비트 gcc는 64 비트 리눅스가 아니라 어쨌든 작동합니다. 내 OP에서와 같이'long long int '에서'mpreal.h'로 구성 할 때 내 자신의 생성자를 작성하지 않으면. – fpghost

+0

위키에서 :'32 비트 Linux, DOS 및 Windows에서 int 및 long은 32 비트이고 long long은 64 비트입니다. 64 비트 Linux에서 int는 32 비트이고 long long long은 64 비트입니다. 이 상황을 설명 할 수 있습니다 생각, mpreal 32 비트 및 경우 int64_t에 대한 생성자 (32x 시스템에서 긴 long int) 정의하는 경우 검사하는 것 같습니다. 그러나 64x 시스템의 경우 long int와 long long int는 동일하므로 원칙적으로 long long int로는 아무도 먹이지 않아야합니다. 그래서 생성자가 정의되지 않았다고 생각합니다. – fpghost

답변

0
  • C standardlong long 최소 64 비트로 표현되어야합니다 확인.

  • 컴파일러가 코드에서 실제로하는 일을 보려면 예를 들어 다음을 사용할 수 있습니다. objdump -D은 이진 파일 (또는 중간 개체 파일)에 있습니다. 32 비트에

  • longlong long에서 캐스팅 경우 데이터가 손실됩니다 아치.

  • 필자가 이해하는 한, 컴파일러는 어떤 생성자를 사용할 지 결정하는 데 문제가있을 수 있습니다. 기본적으로 ctor(int) 또는 ctor(long int)을 사용할 것인지 결정할 수 없습니다.

편집 : c-tor(uint64_t)

#include <stdint.h> 
... 
uint64_t x = 5; 
mpreal myVar(i); 

작품이 정의 (또는 더 나은 명확한 일치하는 항목이 발견 될 수 있다고 말했다)입니다 - 64 비트에 glibc에 대한합니다 ((unsigned) long intuint64_t에 해당 아치 때문에 실제로 정의 됨). 오버로드 된 함수를 처리 할 때 컴파일러에서 사용하는 규칙에서 오류가 발생합니다. 자세한 내용은 C++11 standard/draft을 참조하십시오.

일반적으로 말하자면 코드를 이식성있게 사용하려면 에 정의 된 유형 (예 : uintXX_tintXX_t)을 사용해야합니다. 이러한 유형은 정확한 너비를 제공합니다. 자세한 내용은 위의 위키 링크를 참조하십시오.

+0

32x 시스템에서'MPREAL_HAVE_INT64_SUPPORT'가 (mpreal.h의 일부로 이미 정의되어 있습니다.)이 경우에는 생성자가 존재하며 64 비트 long long int를 사용합니다. 64 비트 시스템에서 일반적으로 long long int를 사용하지는 않지만, long int는 둘 다 64 비트이므로, mpreal.h는 이러한 생성자를 명시 적으로 정의하지 않았습니다. OP에서 보았 듯이 본인을 추가했습니다. 이것은 'long int'생성자와 본질적으로 동일하며, 모든 것들이 컴파일됩니다. 64x에서는 long long int에서 long int 로의 캐스팅이 데이터를 잃지 않는다고 생각합니다. – fpghost

+0

오른쪽, 64 비트'lli -> li'는 데이터를 잃지 않을 것입니다 (실제 타입의 너비에 달렸지 만'li'은 보통 64 비트 아치의 쿼드 워드입니다). – peterph

0

나는 mpreal의 저자에게 물었습니다.이것에 대해 시간 (전체 답변 http://www.holoborodko.com/pavel/mpfr/#comment-7444에있다)을 먼저 64X 시스템에 long long int을위한 새로운 생성자를 구축에 관한 :

>Functions “mpfr_set_ui/si” should be fine. 
>Basically constructor for “long long int” should be equivalent to “long int” one. 

>GNU GCC system makes porting from x32 to x64 a little bit messy. It automatically 
>upgrades integer types to x64 bits, which could easily break code being ported. 

>The best workaround for GCC would be to use types with explicit number of bits: 
>int32_t, int64_t from stdint.h. Then move from x32 to x64 would be painless. 

>However neither authors of MPFR nor developers of numeric libraries follow this  
>standard using “long long int”, “long int”, “intmax_t” all of which means different 
>things on x32 and x64 in GCC world. 

>There is some macro-logic in mpreal.h which tries to make things smooth: 
>(a) for x32 builds we define additional constructors for int64_t (aka “long long int” 
>or “intmax_t”) 
>(b) for x64 builds we remove constructors for such type since “long int” is already 
>64bit wide. 

>Macro MPREAL_HAVE_INT64_SUPPORT plays only “suggestive” role, it is undefined 
>automatically for x64 builds on GCC to avoid clash among integer types. 

>The better way would be to detect bit resolution of all integer types at compile time 
>(using macros or meta-magic similar to boost) and add suitable routines to mpreal 
>class. This could easily grow to be more complex than mpreal itself :) . 

>Maybe I will come up with better solution in future versions, any suggestions are 
>welcome. 

그래서 난에서 확인 작업을 정리하면 문제가 해결 될 것이다 영업에서 내 생성자에서 건물 생각 x64 시스템으로 돌아 가면 다시 제거해야합니다. 그렇지 않으면 충돌이 발생합니다. 그 이유는 MPREAL_HAVE_INT64_SUPPORT 매크로가 32x에서 정의되고 int64_t (32x에서 long long int)의 생성자가 정의되므로 다른 생성자를 추가하면 충돌이 발생하기 때문입니다. 이것이 32 코드 시스템에서 방금 작업 한 이유이기도합니다. 64x 시스템에서는 MPREAL_HAVE_INT64_SUPPORT 매크로가 정의되지 않고 long int이 이미 64 비트이므로 매크로 생성자가 long long int 인 생성자가 필요하지 않으므로 매크로가 정의되지 않고 해당 생성자가 제거됩니다.

관련 문제