5

On my machine PHP_INT_SIZE is 8 but pack('i',1) returns a 4 byte string anyway.

The docs say i is a "signed integer (machine dependent size and byte order)" but that doesn't appear to be true. Is it fixed at 4 bytes?

This means that unpack('i',pack('i',PHP_INT_MAX))[1] !== PHP_INT_MAX on 64-bit machines because half the data is lopped off.

Machavity
  • 30,841
  • 27
  • 92
  • 100
mpen
  • 272,448
  • 266
  • 850
  • 1,236
  • Just reproduced in 64-bit Linux—so it's not necessarily a Windows-only issue due to lack of 64-bit integer. – Álvaro González Jul 16 '14 at 16:33
  • "signed integer (machine dependent size and byte order)" does not mean its size should be equal to `PHP_INT_SIZE`, even if it's what everyone would except. – Holt Jul 16 '14 at 16:34

2 Answers2

3

It's important to remember that PHP is written in C (in other words, it doesn't matter what PHP thinks an int is). Jumping off of the other answer about sizeof(int), it looks like it's a relic of 32 bit C compilers (emphasis mine)

Yes, it depends on both processors (more specifically, ISA, instruction set architecture, e.g., x86 and x86-64) and compilers including programming model. For example, in 16-bit machines, sizeof (int) was 2 bytes. 32-bit machines have 4 bytes for int. It has been considered int was the native size of a processor, i.e., the size of register. However, 32-bit computers were so popular, and huge number of software has been written for 32-bit programming model. So, it would be very confusing if 64-bit computer would have 8 bytes for int. Both Linux and Windows remain 4 bytes for int. But, they differ in the size of long.

So, in short, it could be 2 bytes but only if you have a 16 bit processor. In 32 and 64 bit systems, C seems to say int is 4 bytes in all cases. So, yes, pack('i',1); will always be 4 bytes.

Community
  • 1
  • 1
Machavity
  • 30,841
  • 27
  • 92
  • 100
1

Yes (mostly).


From PHP's source code (pack.c):

switch ((int) code) {
    //...

    case 'i': 
    case 'I':
        INC_OUTPUTPOS(arg,sizeof(int))
        break;

    //...
}

The function uses sizeof(int) (which in your case (and most cases [citation needed]) will be 4), rather than the value of PHP_INT_SIZE. Doesn't fully cover the question on "why?", but as the idea for the function was taken from Perl, PHP could just be going for similar functionality.

username tbd
  • 9,152
  • 1
  • 20
  • 35
  • No. You are wrong. `sizeof(int)` will be different if you are on a 32, or 64 bit machine. – Ryan Jul 16 '14 at 16:44
  • @true Can you provide a citation for that? I know it won't always be the same, but it seems to be 4 for me regardless (and similar results are reported here: http://stackoverflow.com/questions/589575/size-of-int-long-etc) – username tbd Jul 16 '14 at 16:49