I am writing some hardware specific code, where I want to use C Macros, the macro definition would be something like this:-
#define VALIDATE_RESOURCE_AND_ALLOCATE(MODE,RESOURCE1) if(a[MODE][RESOURCE1] != x1) || \
(a[MODE][RESOURCE1] != y1)) \
a[MODE][RESOURCE1]=x3;
Since sometimes I can have more then 1 resource to allocate, such as:-
#define VALIDATE_RESOURCE_AND_ALLOCATE_1(MODE,RESOURCE1,RESOURCE2) if(a[MODE][RESOURCE1] != x1) || \ (a[MODE][RESOURCE1] != y1)) \ a[MODE][RESOURCE1]=x3; if(a[MODE][RESOURCE2] != x1) || \ (a[MODE][RESOURCE2] != y1)) \ a[MODE][RESOURCE2]=x3;
Is there any way I can write a macro, which covers both cases, as it takes variable number of arguments?
I have used variable number of arguments, in macro for printf macros, but then how I will address those arguments, by their respective name, for example, if I modify the MACRO definition such as:0-
#define VALIDA_RESOURCE_AND_ALLOCATE(MODE,.....)
How will I identify RESOURCE1, RESOURCE2?
Your macros have a lot of repeated code in them. Simplifying them helps make a solution more apparent:
Here, it’s clearer that this is simply a repeated invocation of the first macro while iterating through a list of arguments.
Assuming you know that the data types being used here will always be consistent, you can try something like this (untested and written off of the top of my head):
where
sometypeis the data type of the arguments that you will be using forRESOURCE1,RESOURCE2, etc.Given the complexity of what you are trying to do, you’d be a lot better off writing a function to do the iteration instead of a macro. You can still use a macro to create the
RESOURCElist, but don’t try to get the pre-processor to do the iteration for you. If you need to avoid the overhead of a function call (since you tagged this as ’embedded’), you can declare the functionsinlineand the result should be as efficient as using a macro. In the process, though, you’ll gain things like type safety.While it might be technically possible to do this with a macro, it would be a nasty hack that would most likely bring more problems than benefits. Doing complex procedural tasks with the pre-processor rarely turns out well.
The other alternative that you have is to use a code generator that takes a list of
RESOURCEarguments from a file and generates a .c file containing the initialization code. The code generator would be written in a language much more powerful than the C pre-processor (almost any scripting language could be used here). This probably wouldn’t be worth the trouble unless you had a long list ofRESOURCEs, though.