Author Topic: (C programming) X-Macros  (Read 3267 times)

Shelku

  • Community Member
  • Posts: 45
  • Hero Points: 0
(C programming) X-Macros
« on: April 21, 2010, 05:32:16 pm »
I used an X-Macro to define several structs, but SlickEdit can't seem to find the struct elements. Is there a way to get SlickEdit to recognize the X-Macros?

Example:
Code: [Select]
#define CFG_TABLE \
CFG(foo, 10) \
CFG(bar, 20) \
CFG(x, 100)

typedef struct
{
  #define CFG(varName, default) int varName;
  CFG_TABLE
  #undef CFG
} FOO_STRUCT_VARS;

FOO_STRUCT_VARS defaults = {
  #define CFG(varName, default) default
  CFG_TABLE
  #undef CFG
};

// Now SlickEdit doesn't recognize defaults elements:
if (defaults.foo == 10)
« Last Edit: April 22, 2010, 04:23:54 pm by Shelku »

Graeme

  • Senior Community Member
  • Posts: 2422
  • Hero Points: 320
Re: (C programming) X-Macros
« Reply #1 on: April 22, 2010, 12:10:27 pm »
I presume the unreadable macro trickery is to ensure the initialization values match the data.

You possibly meant
FOO_STRUCT_VARS defaults = {
but even so, slick doesn't handle it.  If you rewrite the code as below, you might have a chance of using slick's preprocessing defs mechanism to handle this.  Look up the topic "preprocessing for C++" in the slick help index and note that you can add macros such as these directly to usercpp.h.  This possibly still doesn't help much because every time you change CFG_TABLE you have to update usercpp.h.  And even if you do that, slick possibly still won't handle the typedef!

Maybe it would be better to use slick's column mode to handle this
e.g. below I created abc2 by column selecting the 3,4 column and moving it to the front of the line, then I used column mode to add the , // to all lines simultaneously.

struct abc {
   int v1;  // 3
   int v2;  // 4
};

abc abc2 {
   3, // int v1;  //
   4, // int v2;  //
};


Graeme

Code: [Select]
#define CFG_DECL(varName, default) int varName;
#define CFG_INIT(varName, default) default,

#define CFG_TABLE(CFG_TYPE) \
CFG_TYPE(foo, 10) \
CFG_TYPE(bar, 20) \
CFG_TYPE(x, 100)

typedef struct
{
  CFG_TABLE(CFG_DECL)
} FOO_STRUCT_VARS;

FOO_STRUCT_VARS defaults = {
  CFG_TABLE(CFG_INIT)
};


Shelku

  • Community Member
  • Posts: 45
  • Hero Points: 0
Re: (C programming) X-Macros
« Reply #2 on: April 22, 2010, 03:01:58 pm »
Thanks for the code fix. The example I gave was just to simplify the type of code that I was using.

I know it's preprocessor trickery, but from a coding point of view it is good to have everything related to a variable in one location rather than having to remember to update multiple places in code every time the CFG_TABLE changes. The reason I turned to this X-Macro is because bugs were created several times after new variables were added and the updater forgot to update one of the many places in code. With the X-Macro, only one line needs to be updated and everything else is taken care of automatically. My actual macro has several values like variable name, text name, min, max, default, etc.

In my situation, I don't care so much about every use of the CFG redefinition - I just want to get the base FOO_STRUCT_VARS struct elements so that I can type "defaults.", hit ALT+. and see a list of the struct elements.

If I add CFG(varName, default) int varName; into the C/C++ preprocessing options, then I can at least "go to definition" (CTRL+.), but I don't get the ALT+. list. Can I at least get that part?

Graeme

  • Senior Community Member
  • Posts: 2422
  • Hero Points: 320
Re: (C programming) X-Macros
« Reply #3 on: April 24, 2010, 08:45:53 am »
Quote
If I add CFG(varName, default) int varName; into the C/C++ preprocessing options, then I can at least "go to definition" (CTRL+.), but I don't get the ALT+. list. Can I at least get that part?

I'm not sure what you're asking here.  As far as I can see, the only way to get ALT+. to give you the member list is to copy the CFG table thing to a separate file where you have
typedef struct {
   CFG(foo,10)
   ...
} FOO_STRUCT_VARS;
Then when you change the "CFG table", you have to update both copies if you want the changes to appear in the ALT+. list.  The second file isn't part of your build but if you add a second project to your workspace and add the file to it, slick will tag it.  In the first file, you probably have to hide the definition of FOO_STRUCT_VARS from slick which you can possibly do by
#ifndef SLICKEDIT
typedef struct
{ //...
} FOO_STRUCT_VARS;
#endif
and add SLICKEDIT to your preprocessor list.

If you're using C99, you can use designated initializers to solve this problem.  As far as I know, C++0X doesn't include designated initializers.  I guess the C++ designers don't care about efficiency as much as C and expect this kind of initialization to be done at runtime perhaps.

Graeme