I have this macro code, which allows me to define both a C enum and a list of the enumerated names as strings using one construct. It prevents me from having to duplicate enumerator names (and possibly introducing errors for large lists).
#define ENUM_DEFINITIONS(F) \
F(0, Item1) \
F(5, Item2) \
F(15, Item3) \
...
F(63, ItemN)
then:
enum Items {
#define ITEM_ENUM_DEFINE(id, name) name = id,
ENUM_DEFINITIONS(ITEM_ENUM_DEFINE)
#undef ITEM_ENUM_DEFINE
which, when expanded, should produce:
enum Items {
Item1 = 0,
Item2 = 5,
Item3 = 15,
...
ItemN = 63,
}
In the implementation file, I have this code:
const char* itemNames[TOTAL_ITEMS];
int iter = 0;
#define ITEM_STRING_DEFINE(id, name) itemNames[iter++] = #name;
ENUM_DEFINITIONS(ITEM_STRING_DEFINE)
#undef ITEM_STRING_DEFINE
which, when expanded, produces:
itemNames[iter++] = "Item1";
itemNames[iter++] = "Item2";
itemNames[iter++] = "Item3";
...
itemNames[iter++] = "ItemN";
I'd like to know how many enumerator items I've created in this fashion and be able to pass it to compile-time arrays. In the example above, this would be determining that TOTAL_ITEMS = N at compile-time. Is it possible to count macro invocations in this way?
I've seen mention of a non-standard COUNTER macro, similar to the FILE and LINE macros, but I'm hoping there is a more standard way.
Would also be interested in hearing if there is a better way to achieve this without having to use macros.
The following should work:
#define ITEM_STRING_DEFINE(id, name) #name, // note trailing comma
const char *itemNames[] = {
ENUM_DEFINITIONS(ITEM_STRING_DEFINE)
};
#define TOTAL_ITEMS (sizeof itemNames / sizeof itemNames[0])
Edit: Thank you to Raymond Chen for noting we don't have to worry about the unnecessary final comma in the list. (I had been misremenbering the problem for enums with strict C89 compilers, as in Is the last comma in C enum required?.)
You can use the same technique to count the invocations.
enum itemscounter {
#define ITEM_ENUM_DEFINE(id, name) name##counter,
ENUM_DEFINITIONS(ITEM_ENUM_DEFINE)
#undef ITEM_ENUM_DEFINE
TOTAL_ITEMS
};
Would also be interested in hearing if there is a better way to achieve this without having to use macros.
You could always use a scripting language such as ruby or python to generate .c and .h files for you. If you do it well, you can integrate your script into your Makefile.
I know this isn't a complete answer.
You can create a macro around something like this.
#include <stdio.h>
const char * array[] = {
"arr1", "arr2", "arr3", "arr4"
};
int main (int argc, char **argv)$
{
printf("%d\n", sizeof(array)/sizeof(const char *));
}
If you can modify your enum so it has continous elements you can do sth like this (from Boost)
enum { A=0,B,C,D,E,F,N };
const char arr[N]; // can contain a character for each enum value
See the suggestions Mu Dynamics 'Enums, Strings and Laziness'; these are at least related to what you're after.
Otherwise, look at the Boost Preprocessor collection (which is usable with the C preprocessor as well as the C++ preprocessor).
Related
Can on do this:
#define VARIABLE_LENGTH_CHAR_ARRAY(name, size) \
int temp_array_size_macro_index = size; \
char "#name"[temp_array_size_macro_index];
and in the main use it like:
main(){
VARIABLE_LENGTH_CHAR_ARRAY(local_char_array, 16);
}
would this go against the coding styles or would it be plagued with macro issues?
I know you need to be careful with the variable name!
if I am right you want something like that :
#define VARIABLE_LENGTH_CHAR_ARRAY(name, size) \
const int size_of_##name = size; \
char name[size_of_##name]
int main()
{
VARIABLE_LENGTH_CHAR_ARRAY(local_char_array, 16);
}
The name of the (now const) variable for the size now depends on the name of the array itself, that minimize the probability to have homonyms
The expansion of that code produced by gcc -E gives :
int main()
{
const int size_of_local_char_array = 16; char local_char_array[size_of_local_char_array];
}
But to do that it is strange :
as __J__ I think this not helps to make the program readable
else where in your source size_of_local_char_array can be used but if you/someone search for its definition it will not be found
the macro produces two statements, and of course in that case it is not possible to group them in a block {}, this is dangerous because this is not intuitive. As you can see in your code you added a useless ';' after the use of the macro while a final ';' is already present in the macro definition
C99 allows array initializers (among others) to specify which element of the array is being set with a positive integer designator ($6.7.8.6, $6.7.8.17), for example like so:
const char *foo[] = {[2] = "foo", [1] = "bar", [0] = "baz"};
I have previously used this to make an enum-to-string table like so:
enum {THING_FOO = 0, THING_BAR, THING_BAZ};
const char *table[] = {
[THING_FOO] = "foo",
[THING_BAR] = "bar",
[THING_BAZ] = "baz"
}
However, I am now working under the requirement that my code is c89 compliant.
I have looked into preprocessor magic (as in here, for example) but I need the strings to be arbitrary, not copies of the enum symbols.
It isn't sufficient to just do
enum {THING_FOO = 0, THING_BAR, THING_BAZ};
const char *table[] = {"foo", "bar", "baz"};
because I will need to add enum elements in the future. Using the c99 method, this would result in NULL pointers in the table which are acceptably easy to debug if they become problems. If I forgot to update the string table using this method, I'd get segfaults which are harder to debug. Also it defeats the point of having symbols if I have to remember offsets anyway.
If the declaration were in a function, I could achieve the desired effect like this:
enum {THING_FOO = 0, THING_BAR, THING_BAZ, NUM_THINGS};
void foo(void)
{
static const char *table[NUM_THINGS];
table[THING_FOO] = "foo";
table[THING_BAR] = "bar";
table[THING_BAZ] = "baz";
/* ... */
}
However, at least with gcc, this does not get optimized.
Is there any way of declaring such a string table in c89?
(It's no problem in assembly.)
What about the simple, old fashioned
const char* table[] = { "foo", "bar", "baz" };
In other words, just put them in the correct order.
char *foo_string = table[FOO];
Of course, that only works for simple enums like the above, not for enums in the style
enum { FOO = 13; BAR = 15, BAZ = 312 };
But for that, you would have to create an array with at least 313 elements, most of which are NULL anyway, which would be a pretty wasteful construct. In such cases, the compiler can optimize this for you, when you use a switch construct.
Also take a look at the S.O. question #Leandros pointed to: How to convert enum names to string in c. The answer there uses macros to generate the array, which ensures the entries are in the correct order.
Or, as that answer says:
#define enum_str(s) #s
Which gets rid of the array altogether.
#define DEF_FOO_ENUM(E0, S0, E1, S1, E2, S2) \
enum foo { E0, E1, E2 }; \
const char *foo_str = { S0, S1, S2 };
DEF_FOO_ENUM(THING_FOO, "foo",
THING_BAR, "bar",
THING_BAZ, "baz");
The symbols and strings are paired. You're not easily going to add a new symbol without a string, or vice versa. To add an element, you have to two new arguments to the macro—E3, S3—and so on. There is nothing to keep in sync there, just that the enum has all the E-s and the array has all the S-s. This is almost impossible to screw up.
You can keep them together by using X-Macros:
#define MYXMACRO(OP) \
OP(ENUM_FOO, "foo") \
OP(ENUM_BAR, " bar") \
OP(ENUM_BAZ, "baz")
/* use the first parameter to set up your enums*/
enum {
#define AS_ENUMS(x,y) x,
MYXMACRO(AS_ENUMS)
#undef AS_ENUMS /*not required, just playing nice*/
NUMTHINGS
};
/* use the 2nd parameter to set up your strings*/
const char *strings[] = {
#define AS_STRINGS(x,y) y,
MYXMACRO(AS_STRINGS)
#undef AS_STRINGS
};
#undef MYXMACRO
Now your new data can be added as a set of enum and string. If you later decided to add something else based on the enums it's easily extended with a 'z' parameter to OP() or even ... and __VA_ARGS__ for multiple but varying number of parameters.
After trying a few different techniques, this one is easiest to maintain:
const char *table[] = {
#define FOO 0
"foo",
#define BAR (FOO + 1)
"bar",
#define BAZ (BAR + 1)
"baz"
}
Here all the information about an entry is clustered. To insert an element you only have to modify stuff right around it. For example to insert qux:
const char *table[] = {
#define FOO 0
"foo",
#define QUX (FOO + 1) /* new */
"qux", /* new */
#define BAR (QUX + 1) /* modified */
"bar",
#define BAZ (BAR + 1)
"baz"
}
It's a bit ugly (kind of endearing, you know?) but it works good.
A code snippet like the following:
static const double foo[3] = { 1.0, 2.0, 3.0 };
static const double bar[3] = { foo[0]*foo[0], 3*foo[1], foo[2]+4.0 };
generates a compiler error stating that the initialization values are not constants.
There are some arrays of data (can assume a fixed size) and several other ones, dependent and related to them in fairly simple ways, that would be useful to precompute at compile-time rather than run-time. But since the source data may need to be changed, I would prefer that such changes avoid manually re-computing the dependent arrays.
I suppose one could make some utility that generates a .h file, but at this point I'm curious--is there a way to do something like this (enter the data for a const array only once, but have several other const arrays be dependent on them) in the C preprocessor that's cleaner than (say) defining a preprocessor macro for each and every element of each source array?
P.S. If there's some preprocessor library that could do something like this, I would really appreciate a code example.
It sounds like your original array is actually a list of special constants, and foo is just a collection of them all.
You can achieve something similar using defines and constructing the arrays from those for use in the program later:
#define SpecialA 1.0
#define SpecialB 2.0
#define SpecialC 3.0
static const double foo[3] = { SpecialA, SpecialB, SpecialC };
static const double bar[3] = { SpecialA*SpecialA, 3*SpecialB, SpecialC+4.0 };
After fiddling with the preprocessor some, it turned out to be easier than I thought it would be. The objective was to enter the data for the source array only once while avoiding definitions for every entry individually. This is possible by defining the contents of the array as a preprocessor macro:
#define FOO 1.0, 2.0, 3.0
static const double foo[] = { FOO };
static const double bar[] = { ARR_EL(0,FOO)*ARR_EL(0,FOO), \
3.0*ARR_EL(1,FOO), ARR_EL(2,FOO)+4.0 };
/* Whatever else */
where the helper macros are as follows:
/* ARR_EL(n,...) returns nth element of the array */
#define ARR_EL(n,...) ARR_EL0(ARR_BEGIN(n,__VA_ARGS__))
#define ARR_EL0(...) ARR_ELX(__VA_ARGS__)
#define ARR_ELX(e0,...) (e0)
/* ARR_BEGIN(n,...) returns subarray starting with nth element */
#define ARR_BEGIN(n,...) ARR_BEGIN##n(__VA_ARGS__)
#define ARR_BEGIN0(...) __VA_ARGS__ /* Why is this even here? */
#define ARR_BEGIN1(...) ARR_BEGINX(__VA_ARGS__)
#define ARR_BEGINX(e0,...) __VA_ARGS__
#define ARR_BEGIN2(...) ARR_BEGIN1(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN3(...) ARR_BEGIN2(ARR_BEGIN1(__VA_ARGS__))
#define ARR_BEGIN4(...) ARR_BEGIN3(ARR_BEGIN1(__VA_ARGS__))
/* Extendible in the obvious way */
Tested in gcc (cpp 4.1.1) and tcc, but I believe this should all be standard C99.
Without the extra step provided by the ARR_ELX and ARR_BEGINX macros, the preprocessor sometimes treats FOO as a single argument.
I've got a bunch of C functions which get assigned to an array of function pointers, along the lines of this:
typedef int (*func)(int);
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
func f[] = { SomeLongName1, ... , SomeLongName1000 };
This is a lot of work to create and is prone to errors. For instance, there could be a typo in the function name such that a valid function is still named, but the wrong one. Or, if a new function is added at the end one could forget to go in and explicitly add it to the list of function pointers as well.
In order to avoid having to explicitly declare the array of function pointers I have tried various tricks such as macros, which make the code hard to understand and require knowing how the macro works, and I am generally unsatisfied with them.
What I would like to do is something like this:
typedef int (*func)(int);
func f[] = {
int SomeLongName1(int a) {
// ...
}
// ...
int SomeLongName1000(int a) {
// ...
}
};
This way, the array would be automatically created, and if there was some way to put a null pointer at the end so I can determine how many function pointers there are that would be great as well.
However, the above isn't valid C and I'm coming up empty with any way of accomplishing this. If it is something compiler specific (e.g. a GCC extension) that would be ok.
All the functions are statically known at compile time, so I would like to avoid having to do any run-time initialization of the function pointer array - not that I have found a method to do it that way either.
This related question How to define an array of functions, seems to ask the same question, but does not carry it to its logical conclusion. Specifically, I don't want to have to re-type anything I have already typed so as to save time and avoid errors.
If you don't care about the order of functions in the array, and are willing to use a GCC extension, then you can achieve what you want using a whole bunch of initializer (constructor) functions. This obviously isn't ideal because of the sheer number of extra functions defined, but it is certainly one approach you can consider. It constructs the array at runtime.
Define the function append to append a single function to an array (reallocating if needed). Then, the code is basically
#define ARRAYFUNC(name) int name(int); \
void __attribute__((constructor)) __init_##name(void) { append(func); } \
int name(int a)
ARRAYFUNC(func1) {
...
}
ARRAYFUNC(func2) {
...
}
You could use the C preprocessor (X-Macros) for this:
#include <stdio.h>
// define a list of function names and bodies
#define FUNCS \
FUNC(add, { return a+b; }) \
FUNC(mul, { return a*b; }) \
FUNC(div, { return a/b; })
// let the preprocessor make up the actual function implementations
#define FUNC(name, body) int name(int a, int b) body
FUNCS
#undef FUNC
typedef int (*func)(int, int);
// let the preprocessor populate the array of function pointers
func f[] = {
#define FUNC(name, body) name,
FUNCS
#undef FUNC
};
// use it:
int main () {
int a = 2, b = 3, i = 0;
for (; i < sizeof(f)/sizeof(*f); i++) {
printf("%d\n", f[i](a,b));
}
return 0;
}
The output is:
$ gcc test.c && ./a.out
5
6
0
What I would use to solve such a situation (only if I can't avoid it, of course), is to use preprocessing. Not the one available from the C preprocessor, it does not provide the required functionality in a sensible syntax, but a really powerful one like m4.
With m4, your code could look like this:
define(`functionList', `, 0')
define(`functionArrayMember', `define(`functionList', `$1, 'FunctionList)$1')
define(`buildFunctionArray', `{ functionList }')
int functionArrayMember(SomeLongName1)(int a) {
return a+1;
}
//...
int functionArrayMember(SomeLongName1000)(int a) {
return a+1;
}
func f[] = buildFunctionArray();
You just need to provide the right m4 definition for functionArrayMember() and buildFunctionArray(), and you have the functionality you need.
I do not think there is any other way of doing what want to do.
What you wrote
func f[] = { SomeLongName1, ... , SomeLongName1000 };
already does what is best.
Maybe you could name your functions with an prefix 0000 to 1000, so that you can be sure each function is in the right place in your functions pointer array.
Also, if you really have 1000 different functions, they are surely things in common that could lead you to sort them in several arrays, reducing the numbering effort, and that is less error prone.
Is there a nice way to combine designated initializers from C99, with the result of a malloc?
The following seems to have needless duplication:
typedef struct {
int a, b, c;
} Type;
Type *t = malloc(sizeof *t);
*t = (Type) {
.a = 2,
.b = 3,
.c = 5,
};
Can the use of Type, and *t be removed from the above code?
Since you asked ;) there is one tool in C to avoid explicit duplication of code, macros. That said I don't see a way not to repeat at least the name of the type. But in C++ they can't either, so C is at least as good :)
The easiest I see is
#define DESIGNATE_NEW(T, ...) \
memcpy(malloc(sizeof(T)), \
&(T const){ __VA_ARGS__ }, \
sizeof(T))
which would give
Type *t = DESIGNATE_NEW(Type,
.a = 2,
.b = 3,
.c = 5,
);
this has several advantages.
It initializes all members correctly, even on architectures with non
standard representations of the 0 for float types or pointers.
Other than Keith' version it is "coding style" acceptable since it is just an expression that looks like an initialization and anybody should immediately capture visually what the second code snipset is supposed to do.
NB: Observe the const in the macro, this allows several instances of the compound literal to be folded, if the compiler decides this to be relevant. Also there are means to have a variant where the list of designators is optional, see P99 below.
The disadvantage is the memcpy and I would be happier with an assignment. Second there is no check for failure of malloc before using the result, but one could probably come across with some weirdness to have the code exit nicely.
In P99 I go a slightly different way. There we always have an initialization function for a type, something like
inline
Type* Type_init(Type* t, int a, int b, int c) {
if (t) {
*t = (Type const){ .a = a, .b = b, .c = c };
}
return t;
}
which by macro magic can be made to provide default arguments for a, b and c if they are omitted. Then you can simply use something like
Type *t = P99_NEW(Type, 1, 2, 3);
in your application code. This is better, since it avoids dereferrencing the pointer when the call to malloc failed. On the other hand this reintroduces an order to the initializers, so not perfect either.
You can with a variadic macro. I'm not going to claim that this is a good idea, but it works:
#include <stdlib.h>
#include <stdio.h>
#define CREATE(type, ptr, ...) \
type *ptr = malloc(sizeof *ptr); \
if (ptr) *ptr = (type){__VA_ARGS__}
int main(void)
{
typedef struct {
int a, b, c;
} Type;
CREATE(Type, t, .a = 2, .b = 3, .c = 5);
printf("t->a = %d, t->b = %d, t->c = %d\n", t->a, t->b, t->c);
return 0;
}
Note that I wasn't able to use the usual do { ... } while (0) macro definition trick (it would create a new scope, and t wouldn't be visible), so you'd have to be careful about the context in which you use this.
Personally, I think I'm happier with the needless duplication.
No, that's the only way to use designated initializers. Without the (Type){}, the compiler doesn't know how to validate the contents.