Searching \ for '[pic]: C pointer/union syntax' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/languages.htm?key=c
Search entire site for: 'C pointer/union syntax'.

Exact match. Not showing close matches.
PICList Thread
'[pic]: C pointer/union syntax'
2002\10\15@094823 by mike

flavicon
face
I'm having a problem with Hitech C - I'm sure it's my
non-understanding of C pointer syntax....

I've defined a type to allow access to the bytes withing a long
individually (this appears to be the most code efficient way of
reading byte values into a long):
typedef union {  unsigned long as_long;
struct {
char byte0;
char byte1;
char byte2;
char byte3;
} bytes;

} longbytes;

This works fine, e.g. to read bytes into global adcresult :
longbytes adcresult;

void readadc(void) {
adcresult.bytes.byte2=getbyte();
adcresult.bytes.byte1=getbyte();
adcresult.bytes.byte0=getbyte();
}

Now I want to write a function that reads data into any long by pasing
a pointer to it, e.g. :
long adcresult;
readadc(&adcresult);

However when I try this :
void readadc(longbytes *result) {
*result.bytes.byte2=getbyte();
*result.bytes.byte1=getbyte();
*result.bytes.byte0=getbyte();
}

I get 'Struct/Union required' errors on the 3 assignment lines.
Any suggestions.... (and Yes I DO want to do it this way, as opposed to simply returning
the result, as the latter method gobbles code)

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\15@103452 by mike

flavicon
face
Many  Thnks to andy n1yew for the quick answer to this :

<snip>

> *result.bytes.byte2=getbyte();

Should be either :
(*result).bytes.byte2=getbyte();

or

result->bytes.byte2=getbyte();

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\15@104710 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

You are getting an error because you are not dereferencing the structure
members correctly.

Try:
void readadc(longbytes *result)
{
result->bytes.byte2=getbyte();
result->bytes.byte1=getbyte();
result->bytes.byte0=getbyte();
}

You have also declared the function as accepting a pointer to your longbytes
structure, but are actually passing a pointer to type long which will also
give you a warning.  You can prevent the warning by casting the long as type
longbytes, e.g.:

long adcresult;
readadc((longbytes*) &adcresult);

Personaly I rarely bother with using structures in this manner.  They can be
usefull, but one you start messing around with pointers it gets messy and
you might as well access the bytes within the long directly using pointers,
e.g.

void readadc(long *result)
{
*(((unsigned char *)result)+0) = getbyte();
*(((unsigned char *)result)+1) = getbyte();
*(((unsigned char *)result)+2) = getbyte();
}

This way you have hidden the complexity of the pointers from the calling
function, and you don't have to cast your longs to 'longbytes' everytime you
call this function.  Note that once you start dealing with pointers in PICC,
you will have problems trying to use variables from different banks.
Passing by value avoids this at the expense of memory useage.

HTH

Mike

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\15@105956 by mike

flavicon
face
>Personaly I rarely bother with using structures in this manner.  They can be
>usefull, but one you start messing around with pointers it gets messy and
>you might as well access the bytes within the long directly using pointers,
>e.g.
>
>void readadc(long *result)
>{
>*(((unsigned char *)result)+0) = getbyte();
>*(((unsigned char *)result)+1) = getbyte();
>*(((unsigned char *)result)+2) = getbyte();
>}
Thanks for that hint - makes things much simpler!
Incidentally is there a similar trick for accessing bytes within
global longs without having to use a union, e.g. long reading;
<some twiddlystuff+1> = byte1;

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\15@115857 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

Yes, I use some macros to do this:

#define byte0(x)                (unsigned char)(*(((unsigned char *)&x)+0))
#define byte1(x)                (unsigned char)(*(((unsigned char *)&x)+1))
#define byte2(x)                (unsigned char)(*(((unsigned char *)&x)+2))
#define byte3(x)                (unsigned char)(*(((unsigned char *)&x)+3))

Cheers

Mike

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\15@174625 by William Chops Westfield

face picon face
> >void readadc(long *result)
> >{
> >*(((unsigned char *)result)+0) = getbyte();
> >*(((unsigned char *)result)+1) = getbyte();
> >*(((unsigned char *)result)+2) = getbyte();

Note that this sort of thing raises portability issues WRT "endian-ness",
especially on larger processors.  On some architectures,

       *(((unsigned char *)result)+3)

is the least significant byte of the long, and on others it is the most
significant byte (on PICS, I imagine it depends on whose math library
you're using for multibyte arithmetic.)

BillW

--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics


2002\10\16@024318 by Michael Rigby-Jones

flavicon
face
{Quote hidden}

Yes it does, but using a union shares the same problem AFAIK?  Personaly, I
regard portability on small embedded projects of minor concern.  That
chances the code will never be moved to another architecture, and if it is
then the code is generaly small enough to sort out this minor issues quite
quickly.  Desktop applications are obviously a different matter...

Regards

Mike

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


2002\10\16@034457 by Claudio Tagliola

picon face
The code may not be ported, but the data it produces might just as well be.
I have a network here with Pick's and AMD186 embedded system and a desktop
system running Java client software. All are in some form IEEE complient,
however, they all have different floating point layouts. Luckily, it's only
a little endian and big endian problem and a 'dislocated' sign bit on Pic
CCS C, so it all comes down to some bitshifting, but anoying to have to code
anyhow.

> {Original Message removed}

2002\10\16@040305 by William Chops Westfield

face picon face
   > Note that this sort of thing raises portability issues WRT "endian-ness",
   > especially on larger processors.
   >
   Yes it does, but using a union shares the same problem AFAIK?

Yep.  Probably twice, cause I'm not sure that the actual order of bytes in a
structure is determinable without looking at the generated code (this is
certainly the case with bitfields.  I'm not sure about full-sized bytes.)


   Personaly, I regard portability on small embedded projects of minor
   concern.  That chances the code will never be moved to another
   architecture, and if it is then the code is generaly small enough to
   sort out this minor issues quite quickly.

Agreed.  It's something to notice, but not something to worry about.  The
fact that different math libraries might use different endian-ness would be
a bigger concern than an actual port to another processor.

BillW

--
http://www.piclist.com hint: The PICList is archived three different
ways.  See http://www.piclist.com/#archives for details.


More... (looser matching)
- Last day of these posts
- In 2002 , 2003 only
- Today
- New search...