C portability gotcha, example

Doug Gwyn <gwyn> gwyn at brl-tgr.ARPA
Sun Oct 27 18:26:04 AEST 1985


One of the fellows here ran across a C coding style problem
that caused an application to break when ported from little-
endian machines to a big-endian.  I am posting this to help
those who may encounter similar problems in the future.

/* modeled after a grammar that builds expression trees: */

struct node { int op; struct node *left, *right; double val; }
	*lp, *rp, *p, *makenode();
double value;			/* constant value from lex */
...
p = makenode( 'x', lp, rp );	/* create multiply node */
...
p = makenode( 'k', value );	/* create real constant node */
...
struct node *makenode( op, arga, argb )
int op; struct node *arga, *argb;
{	extern char *malloc();
	struct node *new =
		(struct node *)malloc( sizeof(struct node) );
	if ( new == 0 )
		punt( "no space" );
	switch ( new->op = op )	/* node type */
	{
	case 'x':		/* (binary) multiplication */
		new->left = arga, new->right = argb;
		break;
...
	case 'k':		/* real constant */
		new->val = *(double *)&arga;	/* XXX */
		break;
	}
	return new;
}

The code failed at point "XXX".  The exercise for the
student is to figure out precisely WHY it fails on some
machines but works on others.  Do not post your answers,
unless you think you see a unique twist; this is a
well-known C coding trap that is in violation of
language standards.  A second exercise for the student
is to figure out how to fix this code; note that simply
adding a typecast (struct node *) when the function is
invoked is NOT sufficient.  No need to post these answers
either.  Maybe Laura will include this in her book.



More information about the Comp.lang.c mailing list