Related
I need to have meta-information about structures in my code. So, I've code some combination of C structures (to store meta information) and C preprocessor macros to initialize these structures without much of boilerplate code. Now it looks like this (really, I'm storing a lot more information about fields, but this code is enough for my question):
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
struct meta_field {
const char *name;
size_t offset;
};
struct meta_struct {
const char *name;
size_t size;
struct meta_field fields[];
};
#define META_STRUCT_BEGIN(NAME) \
static struct meta_struct s_meta_##NAME = { \
.name = "" #NAME, \
.size = sizeof(struct NAME), \
.fields = {
#define META_STRUCT_END() ,{NULL, 0}}}
#define META_FIELD(NAME) { .name = "" #NAME, .offset = offsetof(struct CURRENT_META_STRUCT, NAME) }
struct example {
int i;
double d;
};
#define CURRENT_META_STRUCT example
META_STRUCT_BEGIN(CURRENT_META_STRUCT)
META_FIELD(i),
META_FIELD(d)
META_STRUCT_END();
#undef CURRENT_META_STRUCT
It works. But it has a lot of boilerplate still: #define CURRENT_META_STRUCT, usage of CURRENT_META_STRUCT as argument to META_STRUCT_BEGIN(), #undef for CURRENT_META_STRUCT — all of this looks ugly, IMHO.
I know, that it is impossible to define macro by macro (so, META_STRUCT_BEGIN() can not define CURRENT_META_STRUCT). But looking at Branf*ck implementation in C Preprocessor and Boost-PP, I think that it is posisble to implement something which will look like this:
META_STRUCT(example,
META_FIELD(i),
META_FIELD(d)
)
But I can not wrap my head around this preprocessor magic.
Could somebody helps me?
I've read https://github.com/orangeduck/CPP_COMPLETE already, but it didn't help.
Also, it was marked as duplicate of this, but problem is I need to add "default" argument to all generated macro "calls".
Here are some sketch, what I want to achieve:
#define META_FIELD_IMPL(STRUCT, NAME) { .name = "" #NAME, .offset = offsetof(struct STRUCT, NAME) }
#define META_FIELD(NAME) NAME
#define META_STRUCT(NAME, ... ) \
static struct meta_struct s_meta_##NAME = { \
.name = "" #NAME, \
.size = sizeof(struct NAME), \
.fields = { \
/* Each ARG from __VA_ARGS__ is META_FIELD(x) and \
* I need to call META_FIELD_IMPL(NAME, <Expansion of META_FIELD>) \
* for each ARG from _VA_ARGS_ here */ \
{NULL, 0} \
}}
Now in this example there is only one argument for META_FIELD(): NAME, but in real system there are 6 arguments for META_FIELD() and some helper macro which provide "default" values for common cases, so META_FIELD() is necessary and could not be replaced by NAME itself.
And one last complication: such META_STRUCT() could be called as argument to META_FIELD(), because some fields contains pointers to nested meta-structs! Now it is done by declaring named objects for all nested sub-structures, but I want to avoid it too! I understand, that depth of nesting could be limited by some arbitrary constant, it is Ok.
Update: I added this example of what I want to type and what I want to get after preprocessor. I can not figure out how to implement all these macros (marked with /* ??? */). And, yes, I've checked, manually-coded "end result" compiles fine.
enum meta_type { mt_end, mt_int, mt_string, mt_struct };
struct meta_struct;
struct meta_field {
const char *name;
enum meta_type type;
size_t offset;
struct meta_struct *child;
};
struct meta_struct {
const char *name;
size_t size;
struct meta_field *fields;
};
#define META_STRUCT(NAME, ...) static struct meta_struct s_meta_##name = { .name = #NAME, .size = sizeof(struct NAME), .fileds = (struct meta_field[]){ /* ??? */, {NULL, mt_end, 0, NULL}}}
#define META_FIELD_IMPL0(STRUCT, NAME, TYPE, CHILD) { .name = #NAME, .type = TYPE, .offset = offsetof(STRUCT, NAME), .child = CHILD }
#define META_FIELD_IMPL1(NAME, TYPE, CHILD) /* ??? */
#define META_FIELD(NAME, TYPE) META_FIELD_IMPL1(NAME, TYPE, NULL)
#define META_FIELD_SUB(NAME, CHILD) META_FIELD_IMPL1(NAME, mt_struct, CHILD)
#define META_SUBSTRUCT(NAME, ...) (struct meta_struct){ .name = #NAME, .size = sizeof(struct NAME), .fileds = (struct meta_field[]){ /* ??? */, {NULL, mt_end, 0, NULL}}}
/* Example of "input": */
struct child {
int i;
};
struct parent {
int i;
struct child c;
const char *s;
};
META_STRUCT(parent,
META_FIELD(i, mt_int),
META_FIELD_SUB(c,
META_SUBSTRUCT(child,
META_FIELD(i, mt_int)
)
),
META_FIELD(s, mt_string)
);
/* This should give this */
static struct meta_struct s_meta_parent = {
.name = "parent",
.size = sizeof(struct parent),
.fields = (struct meta_field[]) {
{ .name = "i", .type = mt_int, .offset = offsetof(struct parent, i), .child = NULL },
{ .name = "c", .type = mt_struct, .offset = offsetof(struct parent, c), .child = &(struct meta_struct){
.name = "child",
.size = sizeof(struct child),
.fields = (struct meta_field[]) {
{ .name = "i", .type = mt_int, .offset = offsetof(struct child, i), .child = NULL },
{NULL, mt_end, 0, NULL}
}
}
},
{ .name = "s", .type = mt_string, .offset = offsetof(struct parent, s), .child = NULL },
{NULL, mt_end, 0, NULL}
}
};
Here's an approach.
Basic utilities
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
#define COUNT(...) COUNT_I(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1,)
#define COUNT_I(V,_9,_8,_7,_6,_5,_4,_3,_2,X,...) X
This is an indirect glue macro (allowing arguments to expand) and a count macro. The count macro here supports only 9 arguments, but it's easy to expand the pattern. This just expands to the number of arguments passed. I'm assuming you've seen this before, but just in case you haven't, this just works by argument shifting; it indirectly expands the arguments, and each extra argument shift above 1 displaces the number list until something is "above" X, which it expands to.
#define FIRST(...) FIRST_I(__VA_ARGS__,)
#define FIRST_I(X,...) X
#define REST(X,...) __VA_ARGS__
#define EXPAND(...) __VA_ARGS__
...these are operations on tuples. For the purposes of this answer, a tuple is a set of tokens in parentheses. FIRST and REST use tuples as data types (should be obvious; FIRST indirectly grabs the first element, REST expands to everything but that). EXPAND unwraps a tuple.
And the next utility macro:
#define FOREACH(MACRO_,DATA_,TUPLE_) GLUE(FOREACH_I_,COUNT TUPLE_)(MACRO_,DATA_,TUPLE_)
#define FOREACH_I_1(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_)
#define FOREACH_I_2(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_1(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_3(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_2(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_4(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_3(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_5(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_4(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_6(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_5(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_7(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_6(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_8(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_7(MACRO_,DATA_,(REST TUPLE_))
#define FOREACH_I_9(MACRO_,DATA_,TUPLE_) MACRO_(DATA_,FIRST TUPLE_) FOREACH_I_8(MACRO_,DATA_,(REST TUPLE_))
This is the key macro; it is in practice used to apply your structure's type into the lower level macros for each field. Again, this particular code only works with 9 fields per level, but it should be obvious how to extend this (you probably want to support as many levels as your COUNT macro can count to).
The third argument of FOREACH should be a tuple; FOREACH's job is to call your macro on DATA_ and each element of TUPLE_. For example, FOREACH(FIELD,parent,(i,j,k)) expands to FIELD(parent,i) FIELD(parent,j) FIELD(parent,k).
Concept for specific utilities
The core calling structure for the specific utilities uses tuple data types; when used with the FOREACH macro, underlying calls will curry the outer structure type into each call appropriately. The calling structure looks like this:
META_STRUCT(type , FIELD[ , FIELD[ ... ] ] )
...where each FIELD is a 3-tuple:
(name , type , CHILD )
...and each CHILD is a tuple, which is expanded into a .child assignment. META_SUBSTRUCT works similarly. So according to this call structure, your example will actually wind up being called like this:
META_STRUCT(parent, (i, mt_int, (NULL)), (c, mt_struct, META_SUBSTRUCT(child,(i,mt_int,(NULL)))),(s, mt_string, (NULL)));
In practice, META_SUBSTRUCT will actually fully expand. Its expansion will be a "tuple of tokens" that acts as the child assignment; that is, META_SUBSTRUCT will expand to the actual assignments in the substruct surrounded by parentheses. The FOREACH macro is applied to this construct, currying the outer structure and the three arguments of the above 3-tuple into the 4-argument macro APPLY_UTILI_FIELD.
The usage mirrors your usage and adopts to this call structure. For example, META_FIELD(i, mt_int) is just a macro that expands to (i, mt_int, (NULL)).
Specific utilities
#define META_STRUCT_BEGIN(NAME_) \
static struct meta_struct s_meta_##NAME_ = { \
.name = #NAME_, \
.size = sizeof(struct NAME_), \
.fields = (struct meta_field[]) {
#define META_STRUCT(NAME_,...) \
META_STRUCT_BEGIN(NAME_) \
FOREACH(APPLY_META_STRUCT_MACRO,NAME_,(__VA_ARGS__)) \
META_STRUCT_END()
#define META_STRUCT_END() \
{NULL, mt_end, 0, NULL}}}
#define META_SUBSTRUCT(NAME_,...) \
( META_SUBSTRUCT_BEGIN(NAME_) \
FOREACH(APPLY_META_STRUCT_MACRO,NAME_,(__VA_ARGS__)) \
META_SUBSTRUCT_END() )
#define META_SUBSTRUCT_BEGIN(NAME_) \
&(struct meta_struct) { \
.name = #NAME_, \
.size = sizeof(struct NAME_), \
.fields = (struct meta_field[]) {
#define META_SUBSTRUCT_END() \
{NULL, mt_end, 0, NULL}}}
#define APPLY_META_STRUCT_MACRO(DATA_, ARG_) APPLY_UTIL_FIELD(DATA_, EXPAND ARG_)
#define APPLY_UTIL_FIELD(...) APPLY_UTILI_FIELD(__VA_ARGS__)
#define APPLY_UTILI_FIELD( STRUCT_, FIELD_, TYPE_, CHILD_) \
{ .name = #FIELD_, .type = TYPE_, .offset = offsetof(struct STRUCT_, FIELD_), .child = EXPAND CHILD_ },
#define META_FIELD(NAME_, TYPE_) (NAME_, TYPE_, (NULL))
#define META_FIELD_SUB(NAME_, SUB_) (NAME_, mt_struct, SUB_)
Demo
Showing your example
Notes
Nesting
These macros allow nesting indefinitely of META_SUBSTRUCT calls without running into blue paint, since all such macros wind up being evaluated in the argument substitution phase (... argument mentioning __VA_ARGS__ causes all arguments to expand; each level of META_SUBSTRUCT is a top level expansion in this scenario; this condition recurses).
Your six fields
Given you're showing an example with less fields than you're using, you need specifically to tweak your user defined META_FIELD, META_FIELD_SUB, etc macros to produce k-tuples instead of 3-tuples (where k is what you need). Then, just adjust APPLY_UTILI_FIELD's arguments and expansion to match.
Microsoft Compatibility
This code assumes a standard C preprocessor. If you're working on MSVC specifically (which doesn't have one), it won't work. Specifically, MSVC fails to expand __VA_ARGS__ when it's supposed to; if you care to work on MSVC, change the corresponding macros for these three to:
#define COUNT(...) EXPAND(COUNT_I(__VA_ARGS__, 9, 8, 7, 6, 5, 4, 3, 2, 1,))
#define FIRST(...) EXPAND(FIRST_I(__VA_ARGS__,))
#define APPLY_UTIL_FIELD(...) EXPAND(APPLY_UTILI_FIELD(__VA_ARGS__))
The result should also work on standard compliant CPP's.
How about using __VA_ARGS__? Codesnip below accepts maximize 4 fields but you can expands to 5, 6 or more by copy and paste some line of codes (refer here for more detail).
Header file:
#define META_FIELD1(st,x1) { .name = #x1, .offset = offsetof(struct st, x1) }
#define META_FIELD2(st,x1,x2) META_FIELD1(st,x1), META_FIELD1(st, x2)
#define META_FIELD3(st,x1,x2,x3) META_FIELD1(st,x1), META_FIELD2(st,x2,x3)
#define META_FIELD4(st,x1,x2,x3,x4) META_FIELD1(st,x1), META_FIELD3(st,x2,x3,x4)
#define META_FIELD(st, ...) META_FIELD4(st, ##__VA_ARGS__) // limit to 4
#define META_STRUCT(st, ...) \
static struct meta_struct meta_struct_##st = { \
.name = #st, \
.size = sizeof(struct st), \
.fields = { \
META_FIELD(st, ##__VA_ARGS__) \
} \
} \
C file:
struct sample {
int i;
double d;
const char *test;
float t;
};
META_STRUCT(sample, i, d, test, t);
/*
*
*/
int main(int argc, char** argv) {
printf("struct %s { %s, %s, %s, %s } \n",
meta_struct_sample.name,
meta_struct_sample.fields[0].name,
meta_struct_sample.fields[1].name,
meta_struct_sample.fields[2].name,
meta_struct_sample.fields[3].name);
return (EXIT_SUCCESS);
}
Output should be: struct sample { i, i, test, t }
So I have macro like this:
#define some_macro(param1) \
static some_struct_t struct = \
{ \
.param1 = param1 \
}
When I call this macro from main with direct value:
some_macro(50);
I got an error :
..\..\main.c(185): error: #29: expected an expression
I found 2 ways to solve it, first was to declare const value within main and pass to macro and second to change name of parameter not be the same as in macro.
So it works but I do not what caused error. Any ideas?
struct is a reserved word, you can not use it as a variable name
Change to something like:
#define some_macro(p1) \
static some_struct_t valid_var_name = \
{ \
.param1 = p1 \
}
If you want to use the same name of the member (param1) as the name of your macro parameter you need to stop the expansion (using ##) or you get .50 = 50
#define some_macro(param1) \
static some_struct_t varname = \
{ \
.param##1 = param1 \
}
There are a few issues with it.
some_struct_t struct is wrong. if some_struct_t is a typedef for a struct or a define for one, you need to do some_struct_t myStruct else struct some_struct_t myStruct
Another issue is, in the code your macro generates, you'll have something like the following (assuming the problem above is fixed):
struct some_struct_t myStruct = { .50 = 50 };
I believe you didn't intend to use 50 as an identifier :)
This may be more like what you want:
#define some_macro(key, value) \
struct some_struct_t myStruct = {\
.key = value\
}
Or if you already know which variable you want to set:
#define some_macro(value) \
struct some_struct_t myStruct = {\
.param1 = value\
}
struct Error
{
MACRO(1, Connect);
MACRO(2, Timeout);
};
I need to define MACRO() in such way that the above code will generate the following code.
struct Error
{
static const int Connect = 1;
static const int Timeout = 2;
const char * const name[] = {"Connect", "Timeout"};
};
Is this possible or what is the alternative to get what I'm trying to do?
You can't do this directly, but you can if you move the macros to a separate location (such as a separate file):
macros.hpp
MACRO(1, Connect)
MACRO(2, Timeout)
#undef MACRO
the other file
struct Error
{
#define MACRO(a, b) static const int b = a;
#include "macros.hpp"
const char * const name [] = {
#define MACRO(a, b) #b,
#include "macros.hpp"
}
};
Alternatively, you could achieve a similar effect with Boost.Preprocessor.
Here's a Boost.Preprocessor solution:
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/tuple/elem.hpp>
#include <boost/preprocessor/stringize.hpp>
#define FIRST(a, b) a
#define SECOND(a, b) b
#define DECLARE_VAR(r, data, elem) \
static const int FIRST elem = SECOND elem;
#define NAME_ARRAY_ELEM(r, data, elem) \
BOOST_PP_STRINGIZE(FIRST elem),
#define MACRO(seq) \
BOOST_PP_SEQ_FOR_EACH(DECLARE_VAR, ~, seq) \
const char * const name[] = { \
BOOST_PP_SEQ_FOR_EACH(NAME_ARRAY_ELEM, ~, seq) \
}
int main()
{
MACRO(((Connect, 1))((TimeOut, 2)));
return 0;
}
You have to make sure to double bracket each ((Token, value)) pair, however you don't need a separate file for your macro.
What you want, is to have a single list, that will automatically generate the definition and the name list, correct?
If so, search for X Macros in google.
Example:
#define EXPAND_AS_DEFINITION(a, b) static const int b = a;
#define EXPAND_AS_ARRAY(a, b) #b,
#define STATE_TABLE(ENTRY) \
ENTRY(1, Connect) \
ENTRY(2, Timeout)
struct Error
{
STATE_TABLE(EXPAND_AS_DEFINITION)
static const char * const name[];
};
const char * const Error::name[] = {STATE_TABLE(EXPAND_AS_ARRAY) 0};
It looks like like you are trying to define an enum Error that also has the strings as members. I will give you my own solution to this problem. (I'm not addressing the question but I believe that my answer is relevant for what I understand that OP is trying to do.)
And I just realized that OP is targeting C, not C++, so not sure if this can be done...
In MyEnum.hpp
#define MYENUM(X,...) \
struct X { \
enum Enum {__VA_ARGS__}; \
static const std::vector<std::string> names; \
static X::Enum which(const std::string& s) { \
return static_cast<X::Enum>(findEnum(s,names)); \
} \
static std::string str(X::Enum i) { \
return names[i];} \
}
Here findEnum() is just a linear search over the vector that returns the position index (additionally, in my implementation if it doesn't find it it throws an exception with all the possible correct inputs, I also do case insensitive comparison). Note that an ordered map instead of a vector would be more efficient (O(log(n)) instead of O(n)), but I didn't cared much because the size of those things is very small in my case.
Below the previous macro, declare your enum as
MYENUM(Error,Connect,Timeout); // I put the semicolon here not in the macro
And in MyEnum.cpp, add
#include <boost/assign/list_of.hpp>
const std::vector<std::string> Error::names = boost::assign::list_of
("Connect")("Timeout");
(I think that it should be possible to use initialization lists with a modern compiler). The important thing here is to make sure that the order is the same, otherwise it will not work.
Then, you can do stuff like this:
Error::Enum err1 = Error::Connect;
Error::Enum err2 = Error::which("Timeout");
std::cout << "Got " << Error::str(err1) << " error. Not good.\n";
I'm looking for a way to cleanly define an array of strings in PROGMEM for an AVR project. I have a command line processor that needs a list of command strings.
The traditional way to do it on the AVR architecture is to define each string separately, then an array of pointers to those strings. This is extremely verbose and ugly:
typedef struct
{
PGM_P str; // pointer to command string
uint8_t str_len; // length of command string
uint8_t id; // CLI_COM_* ID number
} CLI_COMMAND_t;
const char CLI_STR_TEMP[] PROGMEM = "TEMP";
const char CLI_STR_POWER[] PROGMEM = "POWER";
...
const CLI_COMMAND_t cli_cmd_table[] = { { CLI_STR_TEMP, sizeof(CLI_STR_TEMP), CLI_COM_TEMP },
{ CLI_STR_POWER, sizeof(CLI_STR_POWER), CLI_COM_POWER },
...
};
(CLI_COM_* are enum'ed indicies, but could be replaced by function pointers or something)
This mess could be reduced using macros to define the strings and build the table, something like:
#define FLASH_STRING(NAME...) const char CLI_STR_ ## NAME [] PORGMEM = #NAME;
#define FSTR(NAME...) { CLI_STR_ ## NAME, sizeof(CLI_STR_ ## NAME), CLI_COM_ ## NAME) }
FLASH_STRING(TEMP);
FLASH_STRING(POWER);
CLI_COMMAND_t cli_cmd_table[] = { FSTR(TEMP), FSTR(POWER) };
(untested, btw, but should be fine)
However, I would like to define all my strings only once and have a macro generate both the individual strings and the array of pointers/sizes/enum references.
On the Arduino platform there is a FLASH_STRING_ARRAY macro which I can't quite figure out, but which doesn't seem to compile either. You can see it here: http://pastebin.com/pMiV5CMr Maybe it's C++ only or something. Also it seems like it can only be used inside a function, not globally.
String tables on AVR have long been a pain and inelegant. Short of writing a little program to generate the necessary code it would be nice to have a way to define it with macros.
Bonus points: Generate the CLI_COM_* constants with the same macro, either as an enum or with #defines.
EDIT: I suppose another name for this would be iterative declaration via a macro.
SOLUTION: Thanks to luser, I came up with this solution:
typedef struct
{
PGM_P str; // pointer to command string
uint8_t str_len; // length of command string
uint8_t id; // CLI_COM_* ID number
} CLI_COMMAND_LUT_t;
#define COMMAND_TABLE \
ENTRY(testA) \
ENTRY(testB) \
ENTRY(testC)
enum {
#define ENTRY(a) CLI_COM_ ## a,
COMMAND_TABLE
#undef ENTRY
};
#define ENTRY(a) const char CLI_STR_ ## a PROGMEM = #a;
COMMAND_TABLE
#undef ENTRY
CLI_COMMAND_LUT_t command_lut[] PROGMEM = {
#define ENTRY(a) {CLI_STR_ ## a, sizeof(CLI_STR_ ## a), CLI_COM_ ## a},
COMMAND_TABLE
#undef ENTRY
};
The produces the following output from the preprocessor:
typedef struct
{
PGM_P str;
uint8_t str_len;
uint8_t id;
} CLI_COMMAND_LUT_t;
enum {
CLI_COM_testA, CLI_COM_testB, CLI_COM_testC,
};
const char CLI_STR_testA PROGMEM = "testA"; const char CLI_STR_testB PROGMEM = "testB"; const char CLI_STR_testC PROGMEM = "testC";
CLI_COMMAND_LUT_t command_lut[] PROGMEM = {
{CLI_STR_testA, sizeof(CLI_STR_testA), CLI_COM_testA}, {CLI_STR_testB, sizeof(CLI_STR_testB), CLI_COM_testB}, {CLI_STR_testC, sizeof(CLI_STR_testC), CLI_COM_testC},
};
So all that lot can be wrapped up an a region and I end up with just a simple and most importantly single definition of each command that serves as both its string name and the reference for the code.
Thanks a lot guys, much appreciated!
X-Macros might help.
strings.x:
X(TEMP, "Temp")
X(POWER, "Power")
Usage:
// String concatenation macros
#define CONCAT(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
// Generate string variables
#define X(a, b) const char CONCAT(CLI_STR_, a) [] PROGMEM = b;
#include "strings.x"
#undef X
// Generate enum constants
#define X(a, b) CONCAT(CLI_COM_, a),
enum {
#include "strings.x"
};
#undef X
// Generate table
#define X(a, b) { CONCAT(CLI_STR_, a), sizeof(CONCAT(CLI_STR_, a)), CONCAT(CLI_COM_, a) },
const CLI_COMMAND_t cli_cmd_table[] = {
#include "strings.x"
};
#undef X
This is untested.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
What C macro is in your opinion is the most useful? I have found the following one, which I use to do vector arithmetic in C:
#define v3_op_v3(x, op, y, z) {z[0]=x[0] op y[0]; \
z[1]=x[1] op y[1]; \
z[2]=x[2] op y[2];}
It works like that:
v3_op_v3(vectorA, +, vectorB, vectorC);
v3_op_v3(vectorE, *, vectorF, vectorJ);
...
#define IMPLIES(x, y) (!(x) || (y))
#define COMPARE(x, y) (((x) > (y)) - ((x) < (y)))
#define SIGN(x) COMPARE(x, 0)
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*a))
#define SWAP(x, y, T) do { T tmp = (x); (x) = (y); (y) = tmp; } while(0)
#define SORT2(a, b, T) do { if ((a) > (b)) SWAP((a), (b), T); } while (0)
#define SET(d, n, v) do{ size_t i_, n_; for (n_ = (n), i_ = 0; n_ > 0; --n_, ++i_) (d)[i_] = (v); } while(0)
#define ZERO(d, n) SET(d, n, 0)
And, of course, various MIN, MAX, ABS etc.
Note, BTW, that none of the above can be implemented by a function in C.
P.S. I would probably single out the above IMPLIES macro as one of the most useful ones. Its main purpose is to facilitate writing of more elegant and readable assertions, as in
void foo(int array[], int n) {
assert(IMPLIES(n > 0, array != NULL));
...
The key point with C macros is to use them properly. In my mind there are three categories (not considering using them just to give descriptive names to constants)
As a shorthand for piece of codes one doesn't want to repeat
Provide a general use function
Modify the structure of the C language (apparently)
In the first case, your macro will live just within your program (usually just a file) so you can use macros like the one you have posted that is not protected against double evaluation of parameters and uses {...}; (potentially dangerous!).
In the second case (and even more in the third) you need to be extremely careful that your macros behave correctly as if they were real C constructs.
The macro you posted from GCC (min and max) is an example of this, they use the global variables _a and _b to avoid the risk of double evaluation (like in max(x++,y++)) (well, they use GCC extensions but the concept is the same).
I like using macros where it helps to make things more clear but they are a sharp tool! Probably that's what gave them such a bad reputation, I think they are a very useful tool and C would have been much poorer if they were not present.
I see others have provided examples of point 2 (macros as functions), let me give an example of creating a new C construct: the Finite state machine. (I've already posted this on SO but I can't seem to be able to find it)
#define FSM for(;;)
#define STATE(x) x##_s
#define NEXTSTATE(x) goto x##_s
that you use this way:
FSM {
STATE(s1):
... do stuff ...
NEXTSTATE(s2);
STATE(s2):
... do stuff ...
if (k<0) NEXTSTATE(s2);
/* fallthrough as the switch() cases */
STATE(s3):
... final stuff ...
break; /* Exit from the FSM */
}
You can add variation on this theme to get the flavour of FSM you need.
Someone may not like this example but I find it perfect to demonstrate how simple macros can make your code more legible and expressive.
for-each loop in C99:
#define foreach(item, array) \
for(int keep=1, \
count=0,\
size=sizeof (array)/sizeof *(array); \
keep && count != size; \
keep = !keep, count++) \
for(item = (array)+count; keep; keep = !keep)
int main() {
int a[] = { 1, 2, 3 };
int sum = 0;
foreach(int const* c, a)
sum += *c;
printf("sum = %d\n", sum);
// multi-dim array
int a1[][2] = { { 1, 2 }, { 3, 4 } };
foreach(int (*c1)[2], a1)
foreach(int *c2, *c1)
printf("c2 = %d\n", *c2);
}
If you need to define data multiple times in different contexts, macros can help you avoid have to relist the same thing multiple times.
For example, lets say you want to define an enum of colors and an enum-to-string function, rather then list all the colors twice, you could create a file of the colors (colors.def):
c(red)
c(blue)
c(green)
c(yellow)
c(brown)
Now you can in your c file you can define your enum and your string conversion function:
enum {
#define c(color) color,
# include "colors.def"
#undef c
};
const char *
color_to_string(enum color col)
{
static const char *colors[] = {
#define c(color) #color,
# include "colors.def"
#undef c
};
return (colors[col]);
};
#if defined NDEBUG
#define TRACE( format, ... )
#else
#define TRACE( format, ... ) printf( "%s::%s(%d)" format, __FILE__, __FUNCTION__, __LINE__, __VA_ARGS__ )
#endif
Note that the lack of a comma between "%s::%s(%d)" and format is deliberate. It prints a formatted string with source location prepended. I work in real-time embedded systems so often I also include a timestamp in the output as well.
Foreach loop for GCC, specifically C99 with GNU Extensions. Works with strings and arrays. Dynamically allocated arrays can be used by casting them to a pointer to an array, and then dereferencing them.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define FOREACH_COMP(INDEX, ARRAY, ARRAY_TYPE, SIZE) \
__extension__ \
({ \
bool ret = 0; \
if (__builtin_types_compatible_p (const char*, ARRAY_TYPE)) \
ret = INDEX < strlen ((const char*)ARRAY); \
else \
ret = INDEX < SIZE; \
ret; \
})
#define FOREACH_ELEM(INDEX, ARRAY, TYPE) \
__extension__ \
({ \
TYPE *tmp_array_ = ARRAY; \
&tmp_array_[INDEX]; \
})
#define FOREACH(VAR, ARRAY) \
for (void *array_ = (void*)(ARRAY); array_; array_ = 0) \
for (size_t i_ = 0; i_ && array_ && FOREACH_COMP (i_, array_, \
__typeof__ (ARRAY), \
sizeof (ARRAY) / sizeof ((ARRAY)[0])); \
i_++) \
for (bool b_ = 1; b_; (b_) ? array_ = 0 : 0, b_ = 0) \
for (VAR = FOREACH_ELEM (i_, array_, __typeof__ ((ARRAY)[0])); b_; b_ = 0)
/* example's */
int
main (int argc, char **argv)
{
int array[10];
/* initialize the array */
int i = 0;
FOREACH (int *x, array)
{
*x = i;
++i;
}
char *str = "hello, world!";
FOREACH (char *c, str)
printf ("%c\n", *c);
/* Use a cast for dynamically allocated arrays */
int *dynamic = malloc (sizeof (int) * 10);
for (int i = 0; i < 10; i++)
dynamic[i] = i;
FOREACH (int *i, *(int(*)[10])(dynamic))
printf ("%d\n", *i);
return EXIT_SUCCESS;
}
This code has been tested to work with GCC, ICC and Clang on GNU/Linux.
Lambda expressions (GCC only)
#define lambda(return_type, ...) \
__extension__ \
({ \
return_type __fn__ __VA_ARGS__ \
__fn__; \
})
int
main (int argc, char **argv)
{
int (*max) (int, int) =
lambda (int, (int x, int y) { return x > y ? x : y; });
return max (1, 2);
}
Someone else mentioned container_of(), but didn't provide an explanation for this really handy macro. Let's say you have a struct that looks like this:
struct thing {
int a;
int b;
};
Now if we have a pointer to b, we can use container_of() to get a pointer to thing in a type safe fashion:
int *bp = ...;
struct thing *t = container_of(bp, struct thing, b);
This is useful in creating abstract data structures. For example, rather than taking the approach queue.h takes for creating things like SLIST (tons of crazy macros for every operation), you can now write an slist implementation that looks something like this:
struct slist_el {
struct slist_el *next;
};
struct slist_head {
struct slist_el *first;
};
void
slist_insert_head(struct slist_head *head, struct slist_el *el)
{
el->next = head->first;
head->first = el;
}
struct slist_el
slist_pop_head(struct slist_head *head)
{
struct slist_el *el;
if (head->first == NULL)
return NULL;
el = head->first;
head->first = el->next;
return (el);
}
Which is not crazy macro code. It will give good compiler line-numbers on errors and works nice with the debugger. It's also fairly typesafe, except for cases where structs use multiple types (eg if we allowed struct color in the below example to be on more linked lists than just the colors one).
Users can now use your library like this:
struct colors {
int r;
int g;
int b;
struct slist_el colors;
};
struct *color = malloc(sizeof(struct person));
color->r = 255;
color->g = 0;
color->b = 0;
slist_insert_head(color_stack, &color->colors);
...
el = slist_pop_head(color_stack);
color = el == NULL ? NULL : container_of(el, struct color, colors);
#define COLUMNS(S,E) [ (E) - (S) + 1 ]
struct
{
char firstName COLUMNS ( 1, 20);
char LastName COLUMNS (21, 40);
char ssn COLUMNS (41, 49);
}
Save yourself some error prone counting
This one is from linux kernel (gcc specific):
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) ); })
Another missing from other answers:
#define LSB(x) ((x) ^ ((x) - 1) & (x)) // least significant bit
I also like this one:
#define COMPARE_FLOATS(a,b,epsilon) (fabs(a - b) <= epsilon * fabs(a))
And how you macros-haters do fair floating-point comparisons?
Just the standard ones:
#define LENGTH(array) (sizeof(array) / sizeof (array[0]))
#define QUOTE(name) #name
#define STR(name) QUOTE(name)
but there's nothing too spiffy there.
#define kroundup32(x) (--(x), (x)|=(x)>>1, (x)|=(x)>>2, (x)|=(x)>>4, (x)|=(x)>>8, (x)|=(x)>>16, ++(x))
Find the closest 32bit unsigned integer that is larger than x. I use this to double the size of arrays (i.e. the high-water mark).
also multi-type Minimum and Maximum like that
//NOTE: GCC extension !
#define max(a,b) ({typeof (a) _a=(a); typeof (b) _b=(b); _a > _b ? _a:_b; })
#define min(a,b) ({typeof (a) _a=(a); typeof (b) _b=(b); _a < _b ? _a:_b; })
Pack bytes,words,dwords into words,dwords and qwords:
#define ULONGLONG unsigned __int64
#define MAKEWORD(h,l) ((unsigned short) ((h) << 8)) | (l)
#define MAKEDWORD(h,l) ((DWORD) ((h) << 16)) | (l)
#define MAKEQWORD(h,l) ((ULONGLONG)((h) << 32)) | (l)
Parenthesizing arguments it's always a good practice to avoid side-effects on expansion.
This one is awesome:
#define NEW(type, n) ( (type *) malloc(1 + (n) * sizeof(type)) )
And I use it like:
object = NEW(object_type, 1);
Checking whether a floating point x is Not A Number:
#define ISNAN(x) ((x) != (x))
One (of the very few) that I use regularly is a macro to declare an argument or variable as unused. The most compatible solution to note this (IMHO) varies by compiler.
TRUE and FALSE seem to be popular.