libdbus On ARM Integer Sizes Question

Simon McVittie smcv at collabora.com
Thu Mar 14 12:09:53 UTC 2019


On Thu, 14 Mar 2019 at 19:53:45 +1300, Lawrence D'Oliveiro wrote:
> I’ve just had a bug report filed against DBussy, my Python wrapper for
> libdbus <https://github.com/ldo/dbussy/issues/16>, saying I should use
> longlong instead of long for 64-bit integers on ARM.

This is really a question about portability in general, rather than D-Bus.

If you're writing to Python's C API like dbus-python does, you should
prefer to use dbus_(u)int(16|32|64)_t, which libdbus sets up to be a
typedef for whatever is the right size; or if you don't support non-POSIX
platforms (most prominently Microsoft Visual Studio's C compiler),
you can use POSIX (u)int(16|32|64)_t.

If DBussy uses ctypes or a similar FFI, use a type that is guaranteed to
be a specific size in bits, if one is available. If your FFI requires
you to get this right for yourself, then yes, you will need to use
"long long" for 64-bit integers on any reasonable 32-bit architecture
(including 32-bit x86).

Note that there are several ARM ABIs. Historically they have been 32-bit,
similar to 32-bit x86 (the i386 family); but ARMv8 CPUs can also run
64-bit executables that have a different ABI (referred to as aarch64 or
arm64), similar to 64-bit x86 (variously referred to as x86_64, amd64 or
x64).

> But I thought the convention for Linux, GCC etc was supposed to be
> architecture-independent: “int” is 32 bits, while “long” is 64 on all
> hardware architectures.

No, that's usually only true on 64-bit architectures.

On Linux (and most Unix platforms, but not Windows), long is the same
size as a pointer, so it's 32-bit on 32-bit architectures and 64-bit on
64-bit architectures. Here's a table:

                                      int  long pointer  long long  aka
Unix 32-bit (i386, arm)                32   32    32       64       ILP32
Windows 32-bit (same as Unix)          32   32    32       64       ILP32
Unix 64-bit (x86_64, aarch64/arm64)    32   64    64       64       LP64
Windows 64-bit (not the same as Unix)  32   32    64       64       LLP64

To summarize those, people sometimes say 32-bit Unix and Windows are
"ILP32" architectures, 64-bit Unix architectures are "LP64", and 64-bit
Windows is "LLP64".

Historically there were some LLP64 Unix platforms that used the same
type sizes as 64-bit Windows, but none of them are really relevant
any more: all vaguely mainstream Unix platform developers (including
Linux, *BSD, macOS etc.) seem to have been convinced by the reasoning
in <http://www.unix.org/unix/version2/whatsnew/lp64_wp.html> that LP64
is the easiest model to deal with.

gcc doesn't really have anything to do with it: a version of gcc
configured for a particular operating system has to use whatever type
sizes are set out in the operating system ABI, otherwise it wouldn't
be able to interoperate with OS libraries. A gcc binary that builds
executable code for 64-bit Linux has to use LP64, but a gcc binary that
builds executable code for 64-bit Windows (mingw-w64) must use LLP64.

    smcv


More information about the dbus mailing list