0

long long int与 64 位 Linux 相比,32 位 Linux 系统究竟如何处理?

在我的 32 位系统上,我对 MPFR 数据类型使用C++ 包装器;这个包装器有一个为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转换long int为具有构造函数的语句如果上面的代码在 64 位 Linux 上运行,那么编译器会导致构造不明确的错误。mpreal

我知道有些人会告诉我根本不要long long int在 64 位上使用,但不幸的是,我正在使用另一个库(odeint),它内置在代码中以这种方式构造我给定的多精度数据类型,所以我不'认为我不能改变事情。

无论如何与64位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);
}
4

2 回答 2

1

我向 mpreal.h 的作者询问了这个问题(完整的答案在http://www.holoborodko.com/pavel/mpfr/#comment-7444long long int ),首先是关于在 64x 系统上构建一个新的构造函数:

>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.

因此,我认为从 OP 构建我的构造函数将修复在 x64 系统上正常工作的问题,但如果回到 x32 系统则需要再次删除,否则会导致冲突。原因是MPREAL_HAVE_INT64_SUPPORT宏在 32x 上定义,而构造函数int64_t(又名long long int在 32x 上)被定义,所以添加另一个这样的构造函数会导致冲突;这也是我的代码在 32 系统上开箱即用的原因。在 64x 系统MPREAL_HAVE_INT64_SUPPORT上,宏是未定义的,并且此类构造函数已被删除,因为long int已经是 64 位宽,因此作者不需要long long int构造函数。

于 2012-12-05T10:07:40.687 回答
0
  • 对于各种类型的大小,请检查C 标准long long必须用至少 64 位表示。

  • 要查看编​​译器对您的代码的真正作用,您可以使用例如objdump -D二进制文件(或中间目标文件)。

  • 在 32 位拱门上,如果您从转换为 ,您丢失数据。long longlong

  • 据我了解,编译器可能难以决定使用哪个构造函数(基本上无法决定是否使用ctor(int)or ctor(long int))。

编辑:

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

按照c-tor(uint64_t)定义的方式工作(或者更好地说可以找到明确的匹配) - 因为在 64 位拱门上(unsigned) long int相当于uint64_t(对于 glibc,它实际上是这样定义的)。该错误源于编译器在处理重载函数时使用的规则 - 有关更多信息,请参阅C++11 标准/草案

一般来说,如果您希望您的代码可移植,您应该使用在inttypes.horstdint.h中定义的类型- 这是 C99 - 即uintXX_tintXX_t. 这些类型保证提供准确的宽度,有关更多信息,请参阅上面的 wiki 链接。

于 2012-12-04T16:06:19.490 回答