avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] calling function pointers via pointers ?


From: David Brown
Subject: Re: [avr-gcc-list] calling function pointers via pointers ?
Date: Thu, 29 Sep 2005 16:20:38 +0200

----- Original Message -----
From: "Vincent Trouilliez" <address@hidden>

> On Thu, 2005-09-29 at 14:24 +0200, David Brown wrote:
> > You've picked a chalenge with your complex menu structures, but you are
> > definitely going about it the right way.  Unconstrained arrays are
almost
> > certainly the most elegant way to deal with the structures - when you
figure
> > them out fully, you'll be glad you stuck by it.  Just take it slowly,
> > building your structure piece by small, understandable piece, with
> > carefully-named typedefs.
>
> Okay David, I just reworked my code a bit inspired by your comments and
> declarations example. I am not sure I quite follow the ins and outs of
> the syntax of typedefs, but the following works fine:
>

You are getting very close...

The syntax for typedefs is pretty close to the syntax for declaring a
variable - you just have "typedef" first.  When naming types, it is not a
bad idea to have some sort of naming convention or other way to make it
obvious what is a type and what is a variable or function.  My own habit
(from too much Delphi programming, I guess) is to have type names start with
a capital T for normal types, P for pointer types and F for function pointer
types (normally I'm not a fan of prefixes for names, but I do like "p" on
pointers and "f" on functions - and often a postfix "s" for arrays).  For
commonly-used types, I don't bother - I've used "typedef unsigned char byte"
for years.

>
> typedef struct {
> char name[21];
> void (*fp) (uint8_t);
> }menu_item;
>

Change it to:

typedef void (*FMenuFunc)(uint8_t);
typedef struct {
    char name[21];
    char padding;
    FMenuFunc fp;
} menu_item;

Then I'd have nothing left to complain about (although no doubt others
will - conventions and styles are a matter of taste, after all).  Note the
extra "padding" byte - the compiler will add such a byte anyway, to get
alignments right (the 16-bit function pointer should be aligned on a 16-bit
boundary).  Compile with the "-Wpadded" flag to see where the compiler has
added padding to structures.  Note also the space after the } to improve
legibility, and the indenting (which you may have had already, but lost in
the email).  I'd call the struct "TMenuItem" rather than "menu_item", but
that's purely a matter of choice.

>
> typedef struct menu {
> char title[21];
> uint8_t nb;
> menu_item items[];
> }menu;
>

Drop the "menu" on the first line.  There's no need for it here, so it's
just name-space polution.

> >From my perspective, it's perfect:
>
> 1) menus are defined completely in one single data type/struc, instead
> of having part of the data pulled out (like was suggested earlier).
>

Yes.

> 2) it's scaleable/unconstrained, and doesn't waste a single byte of ROM.
>

Yes.

> What more could I possibly want ? Well, there is one thing actually:
> the pointer points to a function, any function. However if the item is
> actually a sub-menu, then the 'menu_item' structure needs to store a
> pointer to a 'menu' structure, so that I know what sub-menu to run.
> So it would like this:
>
> typedef struct {
> char name[21];
> void (*fp) (uint8_t);
> menu *sub_menu;   // I need to know what sub-menu to run !
> }menu_item;
>
>
> typedef struct menu {
> char title[21];
> uint8_t nb;
> menu_item items[];
> }menu;
>
> But it's a bit strange no ? :-/ How can I declare a pointer of 'menu'
> type... even before said type has been declared ! The two structures
> would be interdependent... no solution in sight ! :o((((
>

You can make forward declarations for use with pointers:

struct TMenu;
typedef struct TMenu const *PMenu;
typedef struct {
    char name[21];
    char padding;
    FMenuFunc fp;
    PMenu subMenu;
} TMenuItem;

typedef struct TMenu {
    char title[21];
    uint8_t nb;
    TMenuItem items[];
} TMenu;

Note that, to match your forward "struct TMenu" definition, you *do* need
the "TMenu" on the first line of the struct.

> I guess this is crap code again... heeelp...
>

You're getting very close now - don't give up!

mvh.,

David

>
> --
> Vince
>
>
>
> _______________________________________________
> AVR-GCC-list mailing list
> address@hidden
> http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
>





reply via email to

[Prev in Thread] Current Thread [Next in Thread]