Best practice in C to support 64-bit or 32-bit address length with same source file ?

Jay Estabrook Jay.Estabrook at hp.com
Sat May 3 23:03:11 UTC 2008


Jim McCarthy wrote:
> 
> Just recently I've gained access to an HP zx6000 Itanium-2 workstation,
> running Scientific Linux for ia64 [a free distro built on RHEL4 sources],
> and I have also noticed the recent announcement of FC9 beta for ia64 ... but
> it seems there is no "ld -taso" linker option on ia64 Linux :-(meaning the C
> source codes I use _will_ require some work, if I want to run on that
> platform )-:
> 
> As I get into modifying C source code on Alpha Linux to enforce 64-bit
> pointer address lengths, rather than have modified source code that _only_
> works on 64-bit machines separate from source code that _only_ works on
> 32-bit machines, it seems preferable to insert branches in the code as
> needed to support either architecture (certainly this is NOT a new/original
> idea :-).  But what is the proper compiler -D<flag> to test against that
> would also work identically on ia64 Linux ?  Granted I'm free (I think) to
> invent a flag with any name I choose, but is there a widely-used convention
> I should follow ?

Proper practice (as Davis expounded well) should see you through any
difficulties of running on different pointer-length machines. Of course,
that's easier said than done when the code is inherited (and perhaps
old), instead of shiny and new... ;-}

Most of the problems I've seen fall into the following category:

Assuming sizeof(integer) == sizeof(pointer)

   Modern C on most machines now establishes:

    sizeof(long integer) == sizeof(pointer)

   so if you MUST live with a program in which is is common to go
   back and forth between something declared "int" and a pointer,
   changing the variable declared "int" to "long" often will do the
   trick.

   And by "trick" I mean it'll work for 32-bit and 64-bit machines.

> Namely, what is the commonly accepted "best practice" for branching in C
> code using
> 
>> #ifdef _______
>>    ...treat address pointers as 64-bit...
>> #else
>>    ...treat address pointers as 32-bit...
>> #endif

Oh, you REALLY don't want to have to do that!!! :-(

There are times, perhaps, with function names that are different
because of the sizes of parameters, say lseek and lseek64, on
some versions of *nix, but those are mostly holdovers that are
disappearing.

> that would work most transparently on Alpha Linux _and_ ia64 Linux ?  (i.e.,
> what -D<flag> should I test against at "______" above ?)  Or is it better to
> insert C code that branches (during execution?) based on some test involving
> sizeof( ) ... or maybe instead use sizeof( ) somehow in declarations so any
> integers equated to address pointers get declared appropriately for either
> 32-bit or 64-bit architectures ?

Most times I've seen such #defines, they have been based on "sizeof".

But as I said, it is pretty common that sizeof(long) and sizeof(pointer)
are the same, regardless of architecture, nowadays. So if the code is
consistent in using "long" in those instances where BOTH must be
containable, it should be OK.

Good luck.

--Jay++





More information about the axp-list mailing list