2

The function:

#define ASSOC(port) (*(volatile bit_field *) (&port))

The function call:

#define SCLK ASSOC(PORTC).bit0

bit_field defined as a struct like this:

typedef struct {
 unsigned char bit0 :1, bit1 :1, bit2 :1, bit3 :1, bit4 :1, bit5 :1,
   bit6 :1, bit7 :1;
} bit_field;

I don't know where &port is defined.

Can someone please explain how the function is read and how it works please? I am not very good with pointers and this example in particular is very confusing with "*" in the front and at the end and the "&" with the port.

Thank you

milan
  • 2,029
  • 7
  • 24
  • 34

3 Answers3

4

port is not defined. It is the argument to ASSOC as you can see here:

#define ASSOC(port) /* etc. */

Also, I assume it is supposed to be a char, because the bit_field has 8 bits. The & in &port simply serves to get its address in memory.

ASSOC in turn casts &port to a volatile bit_field * and then there is the extra * at the beginning to point directly to the contents of the resulting pointer.

Therefore, once you call ASSOC(port), you can use it as a bit_field type structure. For example, the SCLK macro will give the first bit of PORTC.

houbysoft
  • 29,496
  • 22
  • 91
  • 153
  • This took me a while to understand but I get it now. The most confusing part to me was why he was he was defining bit_field as a pointer variable (with the *). It is because he is getting all the contents of the typedef bit_field that he created. Then he deferences the whole thing [(*(volatile bit_field *) (&port))] with the outside * because if he doesn't, he will return the address of what he is passing in (PORTC). So he deferences the whole thing so the contents are returned and not the address.... I am finally understanding pointers better :) – milan Dec 27 '10 at 03:46
2

The ASSOC macro you define is an in-place cast.

  1. You pass in a value port (in this case, it's coming from the other macro SCLK)
  2. ASSOC takes the address of port with the & operator
  3. ASSOC casts port's address to a (volatile bit_field *)
  4. ASSOC dereferences (*s) the address of the bit_field

The result is the same bits as you started with, but usable as a bit_field struct.

Richard
  • 3,198
  • 27
  • 40
  • This took me a while to understand but I get it now. The most confusing part to me was why he was he was defining bit_field as a pointer variable (with the *). It is because he is getting all the contents of the typedef bit_field that he created. Then he deferences the whole thing [(*(volatile bit_field *) (&port))] with the outside * because if he doesn't, he will return the address of what he is passing in (PORTC). So he deferences the whole thing so the contents are returned and not the address.... I am finally understanding pointers better :) – milan Dec 27 '10 at 03:46
1

ASSOC takes what I'm assuming is a char named PORTC and gives back a bit_field with the same values as each individual bit in PORTC.

SCLK returns one of the bits in the bit field.

You're taking PORTC and passing it to ASSOC as the parameter.

Blindy
  • 55,135
  • 9
  • 81
  • 120