I applied X-macro mechanism to get enumeration-to-string relation.
#define CMD_TABLE \
X(cmd_A)\
X(cmd_B)\
////////////////////////////////////
typedef enum
{
EMPTY,
#define X(x) x,
CMD_TABLE
#undef X
}cmd_t;
////////////////////////////////////
const static struct
{
char* name;
cmd_t index;
} conversionMap[] = {
#define X(x) {#x, x},
CMD_TABLE
#undef X
};
Then, this function converts string to enum.
cmd_t str2enum(const char* str);
Finally, corresponding function is called by treating enum as the index of array.
(*func[index])();
This method has a big problem that it force programmer to remember enum-to-function mapping relationship.
In other words, in initialization stage, the order of following functions
void (*func[])(void) =
{
&cmd_A_function,
&cmd_B_function,
};
needs to be as same as that of CMD_TABLE.
Further, once CMD_TABLE grows, code is getting worse to maintain because
if a command is not going to support, people might delete wrong line in array of function pointer.
if I want to know what does cmd_Z do, I have to count up from 1 to 26.
list of CMD_TABLE and void (*func[])(void) will be far away from each other such that programmer needs to write code in two places in order to add one feature.
You have already used X-macro twice.
You can use it a third time.
Here is a proposal how to do that, using the ugly undef-using pattern you applied the first two times:
void (*func[])(void) =
{
#define X(x) &x##_function,
CMD_TABLE
#undef X
};
Related
Consider the following program:
#include <stdio.h>
typedef struct structType {
int someVal;
int otherVal;
// ...more members used for other purposes
} structType;
void myFunc(structType * theStruct, int theVal) {
// Do something
}
int main()
{
structType myStruct;
myStruct.someVal = 5;
myStruct.otherVal = 10;
myFunc(&myStruct, myStruct.someVal);
myFunc(&myStruct, myStruct.otherVal);
return 0;
}
When calling myFunc() I need to pass both a pointer to the struct itself, and one of the values contained withing the struct.
Can I somehow make a macro so that myFunc() could be called something like:
MY_FUNC_MACRO(myStruct, someVal);
MY_FUNC_MACRO(myStruct, otherVal);
So that the struct pointer only needs to be typed once, and then the name of the member variable without passing the struct name once again.
I know about the stringilize macros like # an ##, but afaik that only goes from literal name to string. I need to go the other way, to somehow concatenate multiple strings into one literal name.
You don't need anything fancy
#define MY_FUNC_MACRO(A,B) (myFunc(&(A), (A).B))
works.
It's a little bit fragile though because B could be anything.
If you've got more nested structs and the middle layer is known at compile time, you can do this:
#define MY_FUNC_MACRO(A,B) (myFunc(&(A), (A).memberStruct.B))
I think you can simply use typedef like:
typedef structTypePointer *structType;
and the caller to function turn into:
myFunc(structTypePointer, myStruct.someVal);
or
myFunc(structTypePointer, structTypePointer->someVal);
Suppose we have a function like this:
void WonderfulFunction(float a)
Clearly, we can pass an int to wonderful_function and the C-compiler will promote the int to a float.
However, what about user-defined data types? Suppose we use a typedef statement to give a name/alias to a struct. Is there some way to define a promotion-rule, casting function, or constructor which will automatically convert a primitive to ADT (abstract data type)? I realize this can be done in C++, but this needs to be in C.
We want something like the following code to compile correctly:
// #include <niffty_promoter_castOperator_thing.h>
struct HappyStruct {
int happy_int;
};
typedef struct HappyStruct HappyStruct;
/* prototype */
void AnotherWonderfulFunction(HappyStruct hs)
int main( ) {
int a = 12345;
AnotherWonderfulFunction(a);
// A caster/promoter included in the
// header file specifies how to
// construct a HappyStruct from an int
return 0;
}
void AnotherWonderfulFunction(HappyStruct hs) {
// do stuff;
}
This is "possible" with generic selection (YMMV); this described here is the closest you can get in C11. (In C99, C89 this is not possible at all). Here, AnotherWonderfulFunction(X) is a macro that will expand to (AnotherWonderfulFunction)(AsHappy(X)); the parentheses ensure that the macro is not recursively expanded.
AsHappy(X) is a macro that uses generic selection to choose one from 2 utility functions - HappyAsIs takes a struct HappyStruct as a parameter and returns it as-is, whereas HappyFromInt expects an int argument, and will return it wrapped in a struct. It needs to be done using utility functions, because at least GCC does check the language constraints for other branches, even though they're not evaluated. The original X is then passed to the selected function as an argument.
#include <stdio.h>
struct HappyStruct {
int happy_int;
};
void AnotherWonderfulFunction(struct HappyStruct hs) {
printf("AnotherWonderfulFunction called with hs.happy_int = %d\n", hs.happy_int);
}
struct HappyStruct HappyAsIs(struct HappyStruct s) {
return s;
}
struct HappyStruct HappyFromInt(int val) {
return (struct HappyStruct){ val };
}
#define AsHappy(X) \
_Generic((X), \
struct HappyStruct: HappyAsIs, \
default: HappyFromInt \
)(X)
#define AnotherWonderfulFunction(X) (AnotherWonderfulFunction)(AsHappy(X))
int main(void) {
int a = 42;
float b = 65536.5;
struct HappyStruct c = { 123 };
AnotherWonderfulFunction(a);
AnotherWonderfulFunction(b);
AnotherWonderfulFunction(c);
}
and running the program produces:
% ./a.out
AnotherWonderfulFunction called with hs.happy_int = 42
AnotherWonderfulFunction called with hs.happy_int = 65536
AnotherWonderfulFunction called with hs.happy_int = 123
However, the magic disappears as soon as you take a pointer to a function;
void (*fp)(struct HappyStruct) = AnotherWonderfulFunction;
now of course fp cannot work that way because it is not a macro.
... until you make it one ...
#define fp(X) (fp)(AsHappy(X))
All this is somewhat useless, since C11 supports compound literals:
AnotherWonderfulFunction((struct HappyStruct){ 42 });
so it is of limited use - lots of black magic to save a few keystrokes.
For cases where you only care about the binary representation (i.e., not in the int-to-float case), you can use GCC's __attribute__((transparent_union))
I'm trying to write a macro in C (alas, not C++) in a way to trap certain errors, in particular if I pass a name of the wrong type.
For example, with
typedef int APLNELM;
typedef int APLRANK;
#define IsScalar(a) ((a) == 0)
APLNELM AplNelm = 0;
APLRANK AplRank = 0;
Calling IsScalar (AplRank) is correct because Scalar is a Rank concept, but IsScalar (AplNelm) is wrong because Scalar is not a # elements concept.
Can some clever person find a way to write the IsScalar macro such that it checks the type of the name passed to it to ensure that it is of type APLRANK? Feel free to rewrite the original example in any equivalent way if that provides a solution.
If these are the only two types that will ever be passed into the isScalar macro, then you could do something like this:
#include <stdio.h>
struct APLNELM {
int nelm;
char a[1];
};
struct APLRANK {
int rank;
char a[2];
};
#define isScalar(b) (sizeof b.a == 2)
int main(void) {
// your code goes here
struct APLNELM temp1;
struct APLRANK temp2;
printf("%d\n", isScalar(temp1));
printf("%d\n", isScalar(temp2));
return 0;
}
The output of this code is
0
1
This will work, but I highly suggest you don't use it as it wouldn't be super maintainable:
typedef int APLNELM;
typedef int APLRANK;
typedef unsigned int TYPETRAITS;
#define TRAIT_SCALAR 0x1
#define TYPETRAITS_APLNELM TRAIT_SCALAR /*whatever else you want, up to 32 traits*/
#define TYPETRAITS_APLRANK 0/*whatever else you want, up to 32 traits*/
#define GET_TYPE_TRAITS(X) TYPETRAITS_##X
#define IS_SCALAR(X) (X & TRAIT_SCALAR)
#define IS_TYPE_SCALAR(X) IS_SCALAR(GET_TYPE_TRAITS(X))
int main()
{
const int aplnelm_traints = GET_TYPE_TRAITS(APLNELM);
const int aplrang_traints = GET_TYPE_TRAITS(APLRANK);
const bool is_aplnelm_scalar = IS_TYPE_SCALAR(APLNELM);
const bool is_aplrang_scalar = IS_TYPE_SCALAR(APLNELM);
}
I gived up with following code (requires GNU extensions: typeof and Statement Exprs):
#include <stdio.h>
typedef int APLNELM;
typedef int APLRANK;
#define IsScalar(a) \
({ \
/* Override typedefs in block scope */ \
typedef char APLNELM; \
typedef int APLRANK; \
/* Create variable with typeof(a) type; \
* then compare it by sizeof with APLNELM */ \
typeof(a) b; sizeof b == sizeof(APLNELM); \
})
int main(void)
{
APLNELM a = 5;
APLRANK b = 5;
printf("IsScalar: %d\n", IsScalar(a) ? 1 : 0);
printf("IsScalar: %d\n", IsScalar(b) ? 1 : 0);
return 0;
}
The thing is that typeof(a) is actually not replaced by APLNELM or APLRANK. C is not dynamic language, I agree that struct concept would be better suited for such differentiation.
If you want to define two integer types that are different, the straight typedef approach fails, because typedef creates synonyms for the same type, never creates new types.
There is a manner to create different integer types, but even in this case, there is no way to "detect" them through their values.
For example, observe this code:
enum myint1_e {min1 = -32767, max1 = 32767};
enum myint2_e {min2 = -32767, max2 = 32767};
typedef enum myint1_e integer1_t;
typedef enum myint2_e integer2_t;
integer1_t x1 = 0;
integer2_t x2 = 0;
Now, the two types enum myint1_t and enum myint2_t are different integer types.
See C11: 6.7.2.3.(par.5):
Two declarations of [...] enumerated types which are in different scopes or use different tags declare distinct types.
So, their typedef-ed versions are, too, different.
Thus, the variables x1 and x2 have different types.
The integer value 0 can be assigned to both variables.
Now, if you want to check that the type of a variable is the one that you want, you can try doing that:
#define VERIFY_INT1TYPE(a) ((integer1_t*)(0) == (&a))
But this method only offers a Warning message, and not the "comparisson with value false" that you expected.
Explanation: Although the integer types are, in some way, interchangeable in assignment operations, on the other hand their "pointer to" versions are always different types. Thus, a sentence like x1 == x2 has not any problem at all, but the comparisson of a value of two different pointer types will raise a warning message.
Remark: The expression (integer1_t*)(0) is the NULL pointer cast to type integer1_t*.
Example:
VERIFY_INT1TYPE(x2);
This example raise a warning message when I compiled with GCC.
One possibility is to wrap the integer in a one-field struct, to enforce strong typing. To avoid the final production code being suboptimal, compile twice with different macro definitions; once with structs to detect errors, once without structs for optimal code.
#ifdef STRONG_TYPING
#define TYPE(basetype, field) struct { basetype field; }
#define INITIALIZER(value) {(value)}
#define AS_BASETYPE(field, value) ((value).field)
#else
#define TYPE(basetype, field) basetype
#define INITIALIZER(value) (value)
#define AS_BASETYPE(field, value) (value)
#endif
typedef TYPE(int, alpnelm) APLNELM;
typedef TYPE(int, alprank) APLRANK;
#define IsScalar(a) (AS_BASETYPE(aplrank, a) == 0)
With STRONG_TYPING defined, IsScalar(SomeAplNelm) will give a compiler error. Without STRONG_TYPING, the overhead of structs will be completely gone. Naturally, all modules must to be compiled with the same definition before linking, or your executable is likely to crash.
In your program code, you will have to apply some discipline when it comes to using the macros. Declaration example:
APLNELM MyAplNelm1;
APLNELM MyAplNelm2 = INITIALIZER(0);
Assignment:
AS_BASETYPE(aplnelm, MyAplNelm1) = 0;
AS_BASETYPE(aplnelm, MyAplNelm2) = AS_BASETYPE(aplnelm, MyAplNelm1);
It is still allowed to exchange values between different 'strong' types; as long as you specify the correct type (name of the field in the struct) for each individual value.
AS_BASETYPE(aplnelm, MyAplNelm2) = AS_BASETYPE(aplrank, MyAplRank);
Please note you always need AS_BASETYPE to access a variable of one of the 'strong' types. This will make the code more verbose (please feel free to choose a shorter name for the macro), but there's nothing wrong with that. It's just a notion of metadata you are adding; it should actually improve maintainability.
I want to count the number of members in a structure.
For example:
typedef struct
{
char MrChar;
int MrInt;
long MrLong;
} Bg_Typedef;
Bg_Typedef FooStr;
I create a function prototype that should return number of members in the structure
int NumberOfMem(Bg_Typedef *psStructure);
=> NumberOfMem(&FooStr) should return 3
It can be done with X_MACRO's.
Do something like this:
#define X_BG_MEMBERS \
X(char, MrChar) \
X(int, MrInt) \
X(long, MrLong)
typedef struct {
#define X(type, member) type member;
X_BG_MEMBERS
#undef X
} Bg_Typedef;
Bg_Typedef FooStr;
Define a function which will count the members. Can also just be a variable, but make the variable static const so that it is not overwritten
static int
bg_members_count() {
#define X(_, __) +1
static int COUNT = 0
X_BG_MEMBERS;
#undef X
return COUNT;
}
Now you can do something like this in main:
#include <stdio.h>
...
int main() {
printf("The number of members defined in Bg_Typedef is %d\n", bg_members_count());
}
You should get something like:
The number of members defined in Bg_Typedef is 3
You might also just want a constant, so you can do the following
#define X(_, __) +1
static const int COUNT = X_BG_MEMBERS;
#undef X
Alternative Pattern
In order to avoid having lots of #define X... followed by #undef X, it may be beneficial to do something like this instead:
#define X_BG_MEMBERS(X) \
X(char, MrChar) \
X(int, MrInt) \
X(long, MrLong)
#define BG_STRUCT_FIELD(type, field) type field;
#define BG_COUNT_MEMBER(_, __) +1
typedef struct {
X_BG_MEMBERS(BG_STRUCT_FIELD)
} Bg_Typedefarguably;
static int
bg_members_count() {
static int COUNT = X_BG_MEMBERS(BG_COUNT_MEMBER);
return COUNT;
}
// OR constant
// static const int COUNT = X_BG_MEMBERS(BG_COUNT_MEMBER);
It works the same as the above, but should be noticeably more readable. See ref.
There is no way to do this that is inbuilt into the C language AFAIK. If you want to do this you would need to remember the number of members or hard code the number as return value of your function. C can tell you the size in bytes of your structs but not the number of members they contain. Alternatively you could use a member function of your struct to return the hard coded number of members.
C only allows you to determine the number of bytes a structure requires (including padding bytes) using the sizeof operator. As long as the struct members all have the same type, you can use sizeof(struct foo)/sizeof(membertype) to compute the number of members. In the general case, with differently sized member types, this is impossible from within the C language (you could post process the source automatically and fill in the result, but that's ugly). C simply does not allow what is called Introspection in other languages (like e.g. perl).
But then, you (and the compiler) know the number of members at compile time. Why do you want to compute a known number at runtime? Maybe you can state the actual problem you are trying to solve and we can point to a solution not involving member counts...
This cannot be done in C.
If you really need this, you should try a more high level language which supports reflection. (Java, Python ).
http://en.wikipedia.org/wiki/Reflection_%28computer_programming%29
I have a data structure like this:
struct foo {
int id;
int route;
int backup_route;
int current_route;
}
and a function called update() that is used to request changes in it.
update(42, dont_care, dont_care, new_route);
this is really long and if I add something to the structure I have to add a 'dont_care' to EVERY call to update( ... ).
I am thinking about passing it a struct instead but filling in the struct with 'dont_care' beforehand is even more tedious than just spelling it out in the function call. Can I create the struct somewhere with default values of dont care and just set the fields I care about after I declare it as a local variable?
struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);
What is the most elegant way to pass just the information I wish to express to the update function?
and I want everything else to default to -1 (the secret code for 'dont care')
While macros and/or functions (as already suggested) will work (and might have other positive effects (i.e. debug hooks)), they are more complex than needed. The simplest and possibly most elegant solution is to just define a constant that you use for variable initialisation:
const struct foo FOO_DONT_CARE = { // or maybe FOO_DEFAULT or something
dont_care, dont_care, dont_care, dont_care
};
...
struct foo bar = FOO_DONT_CARE;
bar.id = 42;
bar.current_route = new_route;
update(&bar);
This code has virtually no mental overhead of understanding the indirection, and it is very clear which fields in bar you set explicitly while (safely) ignoring those you do not set.
You can change your secret special value to 0, and exploit C's default structure-member semantics
struct foo bar = { .id = 42, .current_route = new_route };
update(&bar);
will then pass 0 as members of bar unspecified in the initializer.
Or you can create a macro that will do the default initialization for you:
#define FOO_INIT(...) { .id = -1, .current_route = -1, .quux = -1, ## __VA_ARGS__ }
struct foo bar = FOO_INIT( .id = 42, .current_route = new_route );
update(&bar);
<stdarg.h> allows you to define variadic functions (which accept an indefinite number of arguments, like printf()). I would define a function which took an arbitrary number of pairs of arguments, one which specifies the property to be updated, and one which specifies the value. Use an enum or a string to specify the name of the property.
Perhaps consider using a preprocessor macro definition instead:
#define UPDATE_ID(instance, id) ({ (instance)->id= (id); })
#define UPDATE_ROUTE(instance, route) ({ (instance)->route = (route); })
#define UPDATE_BACKUP_ROUTE(instance, route) ({ (instance)->backup_route = (route); })
#define UPDATE_CURRENT_ROUTE(instance, route) ({ (instance)->current_route = (route); })
If your instance of (struct foo) is global, then you don't need the parameter for that of course. But I'm assuming you probably have more than one instance. Using the ({ ... }) block is a GNU-ism that that applies to GCC; it is a nice (safe) way to keep lines together as a block. If you later need to add more to the macros, such as range validation checking, you won't have to worry about breaking things like if/else statements and so forth.
This is what I would do, based upon the requirements you indicated. Situations like this are one of the reasons that I started using python a lot; handling default parameters and such becomes a lot simpler than it ever is with C. (I guess that's a python plug, sorry ;-)
One pattern gobject uses is a variadic function, and enumerated values for each property. The interface looks something like:
update (ID, 1,
BACKUP_ROUTE, 4,
-1); /* -1 terminates the parameter list */
Writing a varargs function is easy -- see http://www.eskimo.com/~scs/cclass/int/sx11b.html. Just match up key -> value pairs and set the appropriate structure attributes.
Since it looks like that you only need this structure for the update() function, don't use a structure for this at all, it will only obfuscate your intention behind that construct. You should maybe rethink why you are changing and updating those fields and define separate functions or macros for this "little" changes.
e.g.
#define set_current_route(id, route) update(id, dont_care, dont_care, route)
#define set_route(id, route) update(id, dont_care, route, dont_care)
#define set_backup_route(id, route) update(id, route, dont_care, dont_care)
Or even better write a function for every change case. As you already noticed you don't change every property at the same time, so make it possible to change only one property at a time. This doesn't only improve the readability, but also helps you handling the different cases, e.g. you don't have to check for all the "dont_care" because you know that only the current route is changed.
How about something like:
struct foo bar;
update(init_id(42, init_dont_care(&bar)));
with:
struct foo* init_dont_care(struct foo* bar) {
bar->id = dont_care;
bar->route = dont_care;
bar->backup_route = dont_care;
bar->current_route = dont_care;
return bar;
}
and:
struct foo* init_id(int id, struct foo* bar) {
bar->id = id;
return bar;
}
and correspondingly:
struct foo* init_route(int route, struct foo* bar);
struct foo* init_backup_route(int backup_route, struct foo* bar);
struct foo* init_current_route(int current_route, struct foo* bar);
In C++, a similar pattern has a name which I don't remember just now.
EDIT: It's called the Named Parameter Idiom.
I'm rusty with structs, so I'm probably missing a few keywords here. But why not start with a global structure with the defaults initialized, copy it to your local variable, then modify it?
An initializer like:
void init_struct( structType * s )
{
memcopy(s,&defaultValues,sizeof(structType));
}
Then when you want to use it:
structType foo;
init_struct( &foo ); // get defaults
foo.fieldICareAbout = 1; // modify fields
update( &foo ); // pass to function
You could address the problem with an X-Macro
You would change your struct definition into:
#define LIST_OF_foo_MEMBERS \
X(int,id) \
X(int,route) \
X(int,backup_route) \
X(int,current_route)
#define X(type,name) type name;
struct foo {
LIST_OF_foo_MEMBERS
};
#undef X
And then you would be able to easily define a flexible function that sets all fields to dont_care.
#define X(type,name) in->name = dont_care;
void setFooToDontCare(struct foo* in) {
LIST_OF_foo_MEMBERS
}
#undef X
Following the discussion here, one could also define a default value in this way:
#define X(name) dont_care,
const struct foo foo_DONT_CARE = { LIST_OF_STRUCT_MEMBERS_foo };
#undef X
Which translates into:
const struct foo foo_DONT_CARE = {dont_care, dont_care, dont_care, dont_care,};
And use it as in hlovdal answer, with the advantage that here maintenance is easier, i.e. changing the number of struct members will automatically update foo_DONT_CARE. Note that the last "spurious" comma is acceptable.
I first learned the concept of X-Macros when I had to address this problem.
It is extremely flexible to new fields being added to the struct. If you have different data types, you could define different dont_care values depending on the data type: from here, you could take inspiration from the function used to print the values in the second example.
If you are ok with an all int struct, then you could omit the data type from LIST_OF_foo_MEMBERS and simply change the X function of the struct definition into #define X(name) int name;
The most elegant way would be to update the struct fields directly, without having to use the update() function - but maybe there are good reasons for using it that don't come across in the question.
struct foo* bar = get_foo_ptr();
foo_ref.id = 42;
foo_ref.current_route = new_route;
Or you can, like Pukku suggested, create separate access functions for each field of the struct.
Otherwise the best solution I can think of is treating a value of '0' in a struct field as a 'do not update' flag - so you just create a funciton to return a zeroed out struct, and then use this to update.
struct foo empty_foo(void)
{
struct foo bar;
bzero(&bar, sizeof (struct bar));
return bar;
}
struct foo bar = empty_foo();
bar.id=42;
bar.current_route = new_route;
update(&bar);
However, this might not be very feasible, if 0 is a valid value for fields in the struct.