php int 32 64,关于64位PHP仍然使用32位数字的问题

首先,我们知道有两个常量。PHP_INT_MAX和PHP_INT_SIZE。

根据PHP官方手册所说,整型数的字长和平台有关,尽管通常最大值是大约二十亿(32 位有符号)。64 位平台下的最大值通常是大约 9E18。PHP 不支持无符号整数。Integer 值的字长可以用常量 PHP_INT_SIZE来表示,自 PHP 4.4.0 和 PHP 5.0.5后,最大值可以用常量 PHP_INT_MAX 来表示。

但是,当我们在Windows下使用64位PHP(版本5.6.4和5.2.17)的时候,PHP_INT_SIZE为4,PHP_INT_MAX为2^31-1。与之相反的是,如果在Linux下使用64位PHP,PHP_INT_SIZE为8,PHP_INT_MAX为2^63-1。PHP Bugs官方也有这么一条BUG报告:https://bugs.php.net/bug.php?id=64863

以下是我的输出D:\Website\IIS>cat int.php

echo 'PHP_VERSION = ' . PHP_VERSION . "\n";

echo 'PHP_INT_MAX = ' . PHP_INT_MAX . "\n";

echo 'PHP_INT_SIZE = ' . PHP_INT_SIZE . "\n";

D:\Website\IIS>php int.php

PHP_VERSION = 5.6.4

PHP_INT_MAX = 2147483647

PHP_INT_SIZE = 4

D:\Website\IIS>php --version

PHP 5.6.4 (cli) (built: Dec 17 2014 13:23:31)

Copyright (c) 1997-2014 The PHP Group

Zend Engine v2.6.0, Copyright (c) 1998-2014 Zend Technologies

with Xdebug v2.2.7, Copyright (c) 2002-2015, by Derick Rethans

D:\Website\IIS>

为什么呢?

还是查代码。

我们可以在PHP的main/main.c中查到REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", sizeof(long), CONST_PERSISTENT | CONST_CS);

嗯,那看来和C语言的long长度有关。那应该是编译器的问题了。

我们知道,PHP在Windows下用的VC++编译器。那试试看咯。

先上代码#include 

#include 

using namespace std;

int main() {

cout <

cout <

cout <

return 0;

}

首先是在x86下编译的结果Z:\>cl /EHsc int.cpp && int

Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x86

Copyright (C) Microsoft Corporation.  All rights reserved.

int.cpp

Microsoft (R) Incremental Linker Version 11.00.60610.1

Copyright (C) Microsoft Corporation.  All rights reserved.

/out:int.exe

int.obj

int (size = 4) max = 2147483647

long (size = 4) max = 2147483647

llong (size = 8) max = 9223372036854775807

Z:\>

再用64位编译器编译吧。Z:\>cl /EHsc int.cpp && int

Microsoft (R) C/C++ Optimizing Compiler Version 17.00.60610.1 for x64

Copyright (C) Microsoft Corporation.  All rights reserved.

int.cpp

Microsoft (R) Incremental Linker Version 11.00.60610.1

Copyright (C) Microsoft Corporation.  All rights reserved.

/out:int.exe

int.obj

int (size = 4) max = 2147483647

long (size = 4) max = 2147483647

llong (size = 8) max = 9223372036854775807

嗯,很好,我们用g++编译器编译呢?$ g++ -v

Using built-in specs.

COLLECT_GCC=g++

COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/lto-wrapper.exe

Target: x86_64-pc-cygwin

Configured with: /cygdrive/i/szsz/tmpp/cygwin64/gcc/gcc-4.8.3-2/src/gcc-4.8.3/configure --srcdir=/cygdrive/i/szsz/tmpp/c

ygwin64/gcc/gcc-4.8.3-2/src/gcc-4.8.3 --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin --libexecdi

r=/usr/libexec --datadir=/usr/share --localstatedir=/var --sysconfdir=/etc --libdir=/usr/lib --datarootdir=/usr/share --

docdir=/usr/share/doc/gcc --htmldir=/usr/share/doc/gcc/html -C --build=x86_64-pc-cygwin --host=x86_64-pc-cygwin --target

=x86_64-pc-cygwin --without-libiconv-prefix --without-libintl-prefix --enable-shared --enable-shared-libgcc --enable-sta

tic --enable-version-specific-runtime-libs --enable-bootstrap --disable-__cxa_atexit --with-dwarf2 --with-tune=generic -

-enable-languages=ada,c,c++,fortran,lto,objc,obj-c++ --enable-graphite --enable-threads=posix --enable-libatomic --enabl

e-libgomp --disable-libitm --enable-libquadmath --enable-libquadmath-support --enable-libssp --enable-libada --enable-li

bgcj-sublibs --disable-java-awt --disable-symvers --with-ecj-jar=/usr/share/java/ecj.jar --with-gnu-ld --with-gnu-as --w

ith-cloog-include=/usr/include/cloog-isl --without-libiconv-prefix --without-libintl-prefix --with-system-zlib --libexec

dir=/usr/lib

Thread model: posix

gcc version 4.8.3 (GCC)

sx@zsx-pc /cygdrive/z

$ g++ int.cpp -o int & ./int

[1] 25508

int (size = 4) max = 2147483647

long (size = 8) max = 9223372036854775807

llong (size = 8) max = 9223372036854775807

比较一下这两个编译器long的size和max,就能知道为什么在老版本PHP中INT_MAX的值不一样了。REGISTER_MAIN_LONG_CONSTANT("PHP_INT_SIZE", SIZEOF_ZEND_LONG, CONST_PERSISTENT | CONST_CS);

所以,PHP7中,应该不会再出现这个问题了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值