[mdlug] C Pointer Problem

A. Zimmer andrew.zimmer at comcast.net
Fri Apr 10 13:16:44 EDT 2015


Hello,

I am attempting to convert a relatively ancient C program (ca. 1999)
into 64-bit clean code that will run on a pure 64-bit Linux system.
The program performs a certain type of digital image processing and it
will run on a 32-bit or multilib (32/64-bit) system, but it will seg fault
on pure 64-bit.

So far I've converted all integer types and corrected all GCC compiler
warnings and errors concerning 32-bit pointers.  The program will now
compile without any problems but will always seg fault during run time.
Using a debugger I've traced the seg faults to some unusual pointer
casts that somehow cause trouble in 64-bit.

Here are two places where segmentation faults occur.  These two functions
are defined in a header file and are used to insert in-line functions
at various places in the code:

#define peiGetFlags(image)	(((imageType*)(image))->flags)
#define peiGetConvKer(image)	(*(imageType**)&(image)->clientData[1])

In these functions, "imageType" is a structure and "image" is a pointer
to that structure.  The gcc compiler won't complain, but when called 
during run time the program seg faults.

I cannot decipher the meaning of the constructs on the right-hand side.

The first seems to cast a pointer into a pointer to imageType, which should
not really be necessary since "image" is already of that type.  In fact,
I can get past the seg fault by rewriting this as "(*image).flags."  But
then why would the original author use this more complicated method?

The second one has me totally baffled.  I can't even guess what that
strange bit-AND is doing.

Can someone shed some light on the meaning of these strange constructs?

Here are two more examples:

#define peiGetConvInt32Factor(image)	(*(int32_t*)&(image)->clientData[3])
#define peiGetConvFloat64Factor(image)	(*(double*)&(image)->clientData[3])

Also, for reference, here is the structure for which these functions are
intended (most of the fields are int32_t):

struct imageType {
	imageOpsType *ops;
	coordType width;
	coordType height;
	int32_t depth;			/* 1..32			*/
	int32_t linebytes;		/* bytes per line		*/
	int32_t allocated;		/* bytes allocated		*/
	pixelType fill;			/* color to fill with		*/
	int8_t sign;
	imageType *primary;		/* for secondary, assoc primary	*/
	coordType primaryX;		/* for secondary, offset in primary */
	coordType primaryY;		/* for secondary, offset in primary */
	int8_t *data;
	uint32_t flags;			/* image access mode(s)		*/
	int32_t verbose;
	int32_t page;			/* number of the current page	*/
	double resX;			/* pixels per unit in X		*/
	double resY;			/* pixels per unit in Y		*/
	int32_t resUnit;			/* 0=nores 1=unk 2=inch 3=cm	*/
	char modes[PEI_MAX_MODES];	/* modes used with open		*/
	char name[PEI_MAX_NAME];
	int32_t clientData[PEI_CLIENT_SIZE]; };


I can always run this code on a multi-lib (32/64-bit) system but I'd like
to use pure 64-bit only.



More information about the mdlug mailing list