[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Need help with afio on powerpc



Michel =?ISO-8859- writes:
> On Tue, 2002-04-30 at 17:21, Michael D. Crawford wrote:
>> [somebody]

>>> I have a Apple. PowerPC 7450 (PowerBook G4). Is it a big or a little
>>> endian system? And where is the difference.
>>
>> I wrote an article about endian issues and some other basics of portable
>> programming at:
>>
>> http://www.byteswap.net/mikesnotes/2002/getting-started/
>
> Great article! We should integrate this into the NM process. :)

No. It's buggy. The advice will fail you on Alpha, UltraSPARC,
IA-64, and any other 64-bit Linux platform:

: A note on using ints as I do in my sample code - they are generally to
: be avoided. Choose shorts or longs, or better still use a typedef to
: the desired type in a header file so it can be redefined for new
: platforms. I use ints here because the Unix system call API's are
: defined to return ints. You cannot in general count on an int having
: the same size even between different compilers on the same machine.

We're doing a 32/64 transition now. Do NOT assume that a long
is fixed size. Feel free to assume that an int is 32 bits;
most new code won't fit on a 16-bit system anyway. Windows 3.1
is dead and buried, along with Minix and Version 6 UNIX.

The C standard allows all sorts of unrealistic crap. Aside from
crummy DSPs like the SHARC where _everything_ is the same size,
the real world is like this:

char is 8 bits, and may be unsigned by default
short is 16 bits
int is 32 bits
long long is 64 bits
if you avoid Win64, sizeof(long)==sizeof(void*)
float is 32 bits, IEEE format
double is 32 bits, IEEE format

Seriously, the sizeof(int)==4 assumption is good forever.
It is required for the natural size progression.

The sizeof(long long)==8 assumption is good for several
decades at least. Most of us will be long long dead by
the time it breaks. We'll hit the Y2.038K bug first.

This is good for Linux, Win32, MacOS, UNIX, and IBM stuff.
So the only question is, do you care about Win64 at all?

Ideally one would use <inttypes.h>, size_t, ssize_t, etc.
Unfortunately C99 isn't common enough to be considered
portable yet. Using printf() requires lots of ugly casts
or lots of ugly macros when working with these types.

(grrr... that is so fixable too, with varargs stuff as
a compiler-builtin instead of nasty macros and a wee bit
of printf awareness, as gcc has via the __attribute__
stuff to make the warnings work right)

: There is a trick in common use in little-endian code that is a serious
: cross-platform no-no; that is casting a pointer to a long to a pointer
: to a char and assuming that the least-significant byte will be at the
: address pointed to:
:
:: unsigned long value = 0x03020100
:: unsigned long *ptr = &value;
:: unsigned char charVal;
::
:: charVal = *(unsigned char*)ptr;	
:
: On a little-endian processor charVal will become 0. On a big-endian
: processor it will become 3. Clearly you do not want to use such code
: in your program but it is very common, and in old code written for one
: little-endian platform it is one of the hardest things to find and
: root out.
:
: To accomplish the same thing in a portable way we use a temporary variable:
:
:: unsigned long temp = *ptr;
:: charVal = (unsigned char)temp;	

Eeew. Just remove the cast. You don't need a temporary.
charVal = *ptr;

: This is done in cooperation with the OS or library memory allocator,
: which always allocates blocks at the largest multiple conceivably
: needed for the architecture, and sometimes a greater value such as the
: multiples of 16 used on the PowerPC MacOS, to discourage blocks from
: taking up more than one cache line.

Wrong. Multiples of 16 are required for AltiVec alignment.
AltiVec is the vector unit. Incorrect alignment generates
incorrect results; the CPU just ignores the low bits!

: One should not design file formats to be written by direct binary
: copies of structures. The objects in file structures should be packed,
: and the data should either be written a field at a time, or for
: greater efficiency a number of fields should be copied from structures
: and packed into a character buffer that is then spit out to disk or
: network.

This isn't required. Look at almost any Linux filesystem driver.
Align things to whatever size they are. (see above) So you'd
never use (long) or (void*) for an on-disk format. For in-memory
use, alignment improves performance; put (long) and (void*)
in between the 32-bit and 64-bit items.


-- 
To UNSUBSCRIBE, email to debian-powerpc-request@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmaster@lists.debian.org



Reply to: