(apologies if the code tags don’t work - I’ve tried 6 times!)
On 2013-03-08, Carlos E. R. <robin_listas@no-mx.forums.opensuse.org> wrote:
> Suppose you do calculations on a big array of integers. You recompile
> for 64 bits, and your integers are “converted”. The array increase in
> size to double the size… even if you do not need huge 64 bit integers.
I’m trying to understand how this conversion would take place as you suggest. For example consider the following basic C++ program (called a.cpp):
# include <iostream>
using namespace std;
int main(int argc, char* argv])
{
int a, b, c;
b = 1;
c = 2;
a = b + c;
cout << a << " = " << b << " + " << c << endl;
cout << sizeof(int) << endl;
return 0;
}
On a 32 bit system, the program would output the sizeof(int) as 4, because `int’ is 32 bits. Now on a 64-bit system:
sh-4.2$ g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib64/gcc/x86_64-suse-linux/4.7/lto-wrapper
Target: x86_64-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib64
--libexecdir=/usr/lib64 --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release
--with-gxx-include-dir=/usr/include/c++/4.7 --enable-ssp --disable-libssp --disable-libitm --disable-plugin
--with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap
--with-slibdir=/lib64 --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch
--enable-version-specific-runtime-libs --enable-linker-build-id --program-suffix=-4.7 --enable-linux-futex
--without-system-libunwind --with-arch-32=i586 --with-tune=generic --build=x86_64-suse-linux
Thread model: posix
gcc version 4.7.1 20120723 [gcc-4_7-branch revision 189773] (SUSE Linux)
sh-4.2$ g++ -S a.cpp
sh-4.2$ ./a.out
3 = 1 + 2
4
sh-4.2$
As you can sizeof(int) is still 4. Now look at an excerpt of 64-bit assembler (generated from g++ -S) in a.s (please
excuse the disgusting AT&T syntax) that is relevant to the 1+2 calculation:
.file "a.cpp"
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.section .rodata
..LC0:
.string " = "
..LC1:
.string " + "
.text
.globl main
.type main, @function
main:
..LFB970:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movl $1, -4(%rbp)
movl $2, -8(%rbp)
movl -8(%rbp), %eax
movl -4(%rbp), %edx
addl %edx, %eax
<SNIP>
Look at the last 5 lines of assembler. You can see that although the base pointer register is 64-bit addressed (%rbp),
the data interval within the stack (for 1 and 2) is 4 bytes (i.e. 32 bits) and loaded into lower 32-bits of the
accumulator and data registers (i.e. eax and edx) using movl (which in Intel syntax is mov ptr dword), meaning 32-bit
integer movement. And you can see the arithmetic itself (addl) is at 32-precision.
So I cannot see how 32 bit integer data are somehow doubled in size when moving from 32-bit to 64-bit architectures
without changes in the code, as you seem to suggest.