[comp.lang.c] Cast struct * --> double * --> struct * Portable ?

dave@dptechno.uucp (Dave Lee) (10/12/90)

Assuming the following :

struct  somestruct  {
	/*** data */
} ;


f_s( s )
struct somestruct *s;
{
	/* do something with s */
}

f_d( d , special )
double *d;
int special;
{

	if( special ) 
		f_s( (struct somestruct *) d );
	else 
		/* Something with a double * */
}	

Will the following call be generally portable ?

struct somestruct THIS_ONE;
	f_d( (double *) &THIS_ONE , 1 );


Restated:  is the following series of casts portable ?

	struct * -->  double * --> struct *  

Does this require that the structure be alligned on a sizeof(double) boundry ?
Would placing a double as the first member of the structure guarentee such
allignment ?   I Believe that if the structure were allocated with malloc()
that the resulting pointer would be worst case alligned and therefore
will not suffer from allignment problems.  How about static or auto structs ?

I understand that this is not good programming, but there exists a large number
of routines in a program that are already coded to expect a double * and I would
prefer not to have to duplicate all that code just to add this special case.

I suspect that this is not truely portable, but are there any "likely" problems
with this?  Is there some kludge I should do to make this work, like placing
a double as the first member of somestruct ?

Please Email or Post as convient. 

-- 
Dave Lee
uunet!dptechno!dave

meissner@osf.org (Michael Meissner) (10/12/90)

In article <588@dptechno.UUCP> dave@dptechno.uucp (Dave Lee) writes:

| Will the following call be generally portable ?
| 
| struct somestruct THIS_ONE;
| 	f_d( (double *) &THIS_ONE , 1 );
| 
| 
| Restated:  is the following series of casts portable ?
| 
| 	struct * -->  double * --> struct *  
| 
| Does this require that the structure be alligned on a sizeof(double) boundry ?
| Would placing a double as the first member of the structure guarentee such
| allignment ?   I Believe that if the structure were allocated with malloc()
| that the resulting pointer would be worst case alligned and therefore
| will not suffer from allignment problems.  How about static or auto structs ?
| 
| I understand that this is not good programming, but there exists a large number
| of routines in a program that are already coded to expect a double * and I would
| prefer not to have to duplicate all that code just to add this special case.
| 
| I suspect that this is not truely portable, but are there any "likely" problems
| with this?  Is there some kludge I should do to make this work, like placing
| a double as the first member of somestruct ?

No, you must have at least one double member within the structure or
union to assure it gets the appropriate alignment.  For passing
generic pointers, consider void * in ANSI systems with a fallback to
char * on moldy old, uncared for systems.  In fact if you want the
strongest alignment requirement within ANSI, it must have a member
whose type is `long double'.

All this aside, it seems a rather dubious programming practice.  I
would recomend, just declaring the pointer to be struct <name> *, and
just not declare <name> within the function.  This is legal, and even
encouraged.  It also should work on most real-world non-ANSI C
compilers.

--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

Do apple growers tell their kids money doesn't grow on bushes?

jfc@athena.mit.edu (John F Carr) (10/13/90)

In article <MEISSNER.90Oct12122323@osf.osf.org> meissner@osf.org (Michael Meissner) writes:
>In fact if you want the
>strongest alignment requirement within ANSI, it must have a member
>whose type is `long double'.

I don't think ANSI guarantees any alignment requirements except that nothing
is less strictly aligned than (void *) and nothing is more strictly aligned 
than the return value of malloc().  I don't know of any machine which aligns
integers more strictly than doubles, but I see nothing in ANSI C to prohibit
this.

--
    John Carr (jfc@athena.mit.edu)