[GRASS-dev] endian & generic library

Glynn Clements glynn at gclements.plus.com
Thu May 11 04:01:40 EDT 2006


Hamish wrote:

> > > Does it make sense to have these functions, string/debug, and memory
> > > related functions in a separate library?  More trouble than it's
> > > worth?
> Glynn:
> > I'm not sure that a library makes sense; it's probably better for
> > import/export modules to do it themselves. Apart from anything else,
> > it allows the compiler to inline the code; such modules will typically
> > be [de]serialising arrays rather than individual integers.
> 
> They are sufficiently abstruse to encourage subtle mistakes, so having
> them predefined somewhere would be nice. ...

I'll have to defer to the opinions of others on that. To me, they look
quite trivial.

It may be more clear to unroll the loops, i.e.:

	void serialize_int32_le(unsigned char *buf, long x)
	{
		buf[0] = (x >>  0) & 0xFF;
		buf[1] = (x >>  8) & 0xFF;
		buf[2] = (x >> 16) & 0xFF;
		buf[3] = (x >> 24) & 0xFF;
	}
	
	void serialize_int32_be(unsigned char *buf, long x)
	{
		buf[0] = (x >> 24) & 0xFF;
		buf[1] = (x >> 16) & 0xFF;
		buf[2] = (x >>  8) & 0xFF;
		buf[3] = (x >>  0) & 0xFF;
	}
	
	long deserialize_int32_le(const unsigned char *buf)
	{
		return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
	}
	
	long deserialize_int32_be(const unsigned char *buf)
	{
		return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
	}

[There was a typo in my previous email; the last two functions both
had the _le suffix.]

> What if the endian
> transforms were written as macros (or inline functions) that could be
> #included from a header file when needed? Does that solve both problems?
> The alternative is cut&paste into each module and hope that down the
> road no one changes one version but not the others.

Both macros and inline functions have problems of their own. The main
problem with macros is that macro calls look like function calls but
don't necessarily behave like them; if this results in a bug, it can
be very hard to track down. The main problem with inline functions is
the compiler isn't guaranteed to inline them.

Between the two, I'd suggest macros, e.g.:

	#define serialize_int32_le(buf, x)	\
	do {					\
		(buf)[0] = ((x) >>  0) & 0xFF;	\
		(buf)[1] = ((x) >>  8) & 0xFF;	\
		(buf)[2] = ((x) >> 16) & 0xFF;	\
		(buf)[3] = ((x) >> 24) & 0xFF;	\
	} while(0)
		
	#define serialize_int32_be(buf, x)	\
	do {					\
		(buf)[0] = ((x) >> 24) & 0xFF;	\
		(buf)[1] = ((x) >> 16) & 0xFF;	\
		(buf)[2] = ((x) >>  8) & 0xFF;	\
		(buf)[3] = ((x) >>  0) & 0xFF;	\
	} while(0)
	
	#define deserialize_int32_le(buf) \
		((buf)[0] | ((buf)[1] << 8) | ((buf)[2] << 16) | ((buf)[3] << 24))
	
	#define deserialize_int32_be(buf) \
		(((buf)[0] << 24) | ((buf)[1] << 16) | ((buf)[2] << 8) | (buf)[3])

> Glynn:
> > SUBMITTING isn't supposed to be a tutorial on C programming
> > (even if many contributors badly need one).

In retrospect, I'd like to apologise for the unnecessarily snarky tone
of that comment.

> Many of us are researchers who know a little C programming, not the
> other way around. We are lucky to have a few experts around to help
> point out the errs of our ways, but still we need all the help and
> on-the-job training we can get. It may be redundant and beyond the scope
> of the SUBMITTING document to recreate K&R in full, but it wouldn't hurt
> to throw in a small reference section at the end of the document
> pointing to some background info on safe strings, pointers, memory
> allocation, etc., usage; links to other project's SUMITTING files..

But what to include?

A SUBMITING file is normally used for issues which are specific to
that particular project.

I'd suggest including a list of common errors, but there aren't really
any specific errors which occur frequently. Which isn't really
surprising given that GRASS consists of so many different types of
code.

-- 
Glynn Clements <glynn at gclements.plus.com>




More information about the grass-dev mailing list