-1

I'm looking through the code of a simple USB driver, and I've come across a line that I don't really understand:

struct UsbDevice
{
    ...
    void (*DeviceDetached)(struct UsbDevice *device) __attribute__((aligned(4)));
    ...
};

What exactly is happening here? This use of the parentheses (to...assign a new name to *device?) and this use of "void" are both new to me. (And the self-referencing struct is also odd.)

2 Answers2

2

This declares a function pointer, called DeviceDetached, that returns void and takes a pointer to a struct UsbDevice. The __attribute__((aligned(4))) forces alignment on a four-byte boundary. You can use the C11 _Alignas.

See What is the meaning of "__attribute__((packed, aligned(4))) " for more information on __attribute((aligned(4)).

Community
  • 1
  • 1
lost_in_the_source
  • 10,998
  • 9
  • 46
  • 75
1

This declares a field in the struct which is a function pointer.

void (*DeviceDetached)(struct UsbDevice *device)
^^^^  ^  ^^^^^^^^^^^^       ^^^^^^^
 |    |   field name        argument list
 |    |
 |    +- pointer type
 |
 +- return type

Note that all the parentheses are required to designate this as a function pointer. It is more common to typedef the function pointer type and then use the typedef'd name to declare struct fields or variables.

The __attribute__ part is a GCC extension to C to indicate that the field should be aligned on a 4-byte boundary, regardless of what the "natural" alignment of the type would be. C11 has a standardised mechanism for this (_Alignas) but compilers have only recently started supporting this.

pmdj
  • 22,018
  • 3
  • 52
  • 103