Struct initialisation through macro overuse

I've got some structs to initialise, which would be tedious to do manually. I'd like to create a macro that will help me with it... but I'm not sure C preprocessor is good enough for this.

I've got structs which represent menus. They consist of function pointers only:

typedef uint8_t (*button_handler) (uint8_t); typedef void (*pedal_handler) (void); typedef void (*display_handler) (void); typedef void (*menu_switch_handler) (void); #define ON_BUTTON(x) uint8_t menu_frame_##x##_button (uint8_t button) #define ON_PEDAL(x) void menu_frame_##x##_pedal (void) #define ON_DISPLAY(x) void menu_frame_##x##_display (void) #define ON_SWITCH(x) void menu_frame_##x##_switch (void) typedef struct menu_frame { button_handler on_button; pedal_handler on_pedal; display_handler on_display; menu_switch_handler on_switch; } menu_frame;

That allows me to write the functions and separate functions as (.c file):

ON_BUTTON(blah) { ... }

and menus as (.h file):

ON_BUTTON(blah); ON_DISPLAY(blah); menu_frame menu_frame_blah = { menu_frame_blah_button, NULL, menu_frame_blah_display, NULL };

Is there any way I can fold the menu definition into one define? I could do something that expands MENU(blah, menu_frame_blah_button, NULL, menu_frame_blah_display, NULL) of course, but is there any way to:

  • make it shorter (NULL or some name)
  • remove the need of ON_BUTTON(...); from before the struct

Ideally, I'd like MENU(blah, button, NULL, display, NULL) to both define the handlers and the menu struct itself. I don't know for example how to prevent expanding the last term into ON_SWITCH(NULL).

Or maybe I should approach it from some other way?

-------------Problems Reply------------

You cannot do conditional macro expansion in C, so that your macro would be expanded differently depending on the arguments, as in: you cannot use #if within macro definition.

I guess the best you could get would be something like MENU(blah, ITEM(blah,button), NULL, ITEM(blah,display), NULL), and you still need a separate set for prototypes because of lack of conditional expansion.

Personally, I would write a simple script to generate that sort of boilerplate C code. One that would understand your desired syntax. In Python or whatever suits you best…

I've written Python scripts to generate this sort of code for me before. You may want to go that route and just work the script into your build process.

You can program conditionals, finite loops, default arguments and all such stuff in the preprocessor alone. The Boost library has an implementation of some of that in their preprocessor section. Boost is primarily for C++, but the preprocessor stuff should basically work in C as well.

By such techniques you can write complicated macros but that are simple to use. It gets a bit simpler to implement when using C99 instead of C89 (you have named initializers and VA_ARGS), but still.

Category:c# Views:1 Time:2010-07-15

Related post

  • Initializing a struct in a macro in a header, must work in both C and C++ source 2011-11-02

    struct info _info; #define INIT(a, b, c, d) \ struct info _info = {a, b, c, d} This worked in C, but with the g++ I get: error: redefinition of ‘info _info’ INIT isn't always called, sometimes _info gets initialised some other way so that's why both

  • Convenient C++ struct initialisation 2011-05-30

    I'm trying to find a convenient way to initialise 'pod' C++ structs. Now, consider the following struct: struct FooBar { int foo; float bar; }; // just to make all examples work in C and C++: typedef struct FooBar FooBar; If I want to conveniently in

  • C++ Struct initialisation problem 2010-09-30

    This c++ code is working fine , however memory validator says that I am using a deleted pointer in: grf->filePath = fname; Do you have any idea why ? Thank you. Dirloader.h // Other code class CDirLoader { public: struct TKnownGRF { std::string fi

  • Problem definition of struct in Macro 2011-03-22

    I'm working on macros in C, trying to simulate the objet behavior but using C and I'm having a problem with the definition of a variable defined from a struct in another struct in a macro. That's my code... it works: #include <stdio.h> #include

  • trying to copy struct members to byte array in c 2009-01-27

    I am attempting to copy the members of a struct containing a mixture of ints, char's and arrays of chars into a byte array to send to a serial line. So far I have struct msg_on_send { char descriptor_msg[5]; int address; char space; char cmdmsg[5]; c

  • Which is best for data store Struct/Classes? 2009-12-23

    We have seen lots of discussion in SO regarding the class vs struct in c#. Mostly ended with conclusions saying its a heap/stack memory allocation. And recommending to use structs in small data structures. Now I have a situation to decide the simple

  • Macro with "placeholder" value 2011-05-21

    I'm working with a library that includes a set of preprocessor libraries. One of them is a FOR_EACH style macro which iterates over a __VA_ARGS__ and calls a user-provided macro for each argument. The user provided macro is called like: SOME_MACRO(cu

  • union initialisation 2011-05-28

    I'm attempting to globally initialise a union as in the following example: #include <cstdio> typedef union { char t[4]; int i; } a; enum { w = 5000, x, y, z }; a temp = {w}; int main() { printf("%d %d %d %d %d\n", temp.t[0],temp.t[1],temp.t[2],

  • Using struct in different .cpp file 2011-07-30

    I have two .cpp files in one project, main.cpp and myfile.cpp I have globaly defined struct mystruct in main.cpp, now I want to use this struct in myfile.cpp. When I write mystruct in a header file and include in both cpp files I get an error, saying

  • C: bitwise not of a struct 2011-10-20

    Possible Duplicate: How do you compare structs for equality in C? In a macro I need the bitwise not of a variable or struct which is a parameter of this macro. #define THE_C_MACRO(var) (someFunction(~var == var##_inv)) That works fine with variables

  • Type-safe generic containers with macros 2012-02-22

    I'm trying to make a type-safe generic linked list in C using macros. It should work similarly to how templates work in C++. For example, LIST(int) *list = LIST_CREATE(int); My first attempt was for #define LIST(TYPE) (the macro I used above) to defi

  • Best way to handle memory allocation in C? 2009-04-06

    I think I've got a good grasp on how to handle memory in C++ but doing it in C is different I'm a bit off. In C++ I've got constructors and destructors, I've got the pretty straightforward new and delete and I know how to encapsulate it using RAII, u

  • need to free a mutex? 2012-02-01

    I have a very simple (sample) C program as follows. I want to ensure I release any resources necessary so that valgrind does not complain. Do I need to free mutex1? Or do anything before the program terminates? Or is the mutex1 not allocate memory? 0

  • Class layout in C++: Why are members sometimes ordered? 2008-11-14

    The C++ standard dictates that member variables inside a single access section must be layed out in memory in the same order they were declared in. At the same time, compilers are free to choose the mutual ordering of the access sections themselves.

  • Wanted: a C++ template idea to catch an issue, but at compile time? 2009-02-04

    We have a const array of structs, something like this: static const SettingsSuT _table[] = { {5,1}, {1,2}, {1,1}, etc }; the structure has the following: size_bytes: num_items: Other "meta data" members So the "total size" is size_bytes*num_items for

  • How do you check if a pointer, in C, is of a certain type? 2009-06-04

    How do you check if a pointer is of a certain type? Using sizeof is not sufficient. I am trying to avoid putting id-numbers into my structs to identify their type. The assumption is that maybe gcc puts a struct definition somewhere in the process, an

  • How to check for NULL in c++? 2009-09-23

    Let say for example, I have a struct, and an array of the struct. What I want to do is to iterate through the array and check if any of the item is a null. I tried checking the item against NULL and (struct *) 0, that don't seem to work. Is there any

  • How do I specialize a templated class for data type classification? 2010-02-10

    We use boost - so using that library should be fine. But I've never managed to wrap my head around creating a set of templates which give you the right specialization for a whole class of data types, as opposed to specializing for a single data type

  • Is C a middle-level language? 2010-05-25

    In programming language discussions we hear terms such as low-level, middle-level, and high-level. How are these determined? Would C be considered a middle-level language? --------------Solutions------------- Low-, high-, blah-level is all just vague

Copyright (C), All Rights Reserved.

processed in 0.137 (s). 11 q(s)