Passing values to macros by for loop - c

I want to pass values to the macro through for loop,but when i try to pass values it gives error, please help m as fast as possible. When values of i are passed to macro as Valve(i) it gives error
my code given below:
#define Valve(x) stTest.bValve##x##_Cmd
typedef struct OperationFlags
{
int bValve1_Cmd;
int bValve2_Cmd;
}FLAGS_TypeDef;
void main(void)
{
FLAGS_TypeDef stTest;
int j,i;
stTest.bValve1_Cmd = 4;
stTest.bValve2_Cmd = 9;
for(i=1;i<=2;i++)
{
j=Valve(1);
printf("%d",j);
}
}

It is normal!
The preprocessor (the "thing" that processes the macros) is run BEFORE the C compiler. So, it is only valid when it produces compilable code.
In your case, if you use the code you show
j=Valve(1)
it will work for that value, since it will produce:
j=stTest.bValve1_Cmd
but it will do the entire loop only with that value.
When you change the parameter "1" with the "i" for actually doing the loop, then it will produce:
j=stTest.bValvei_Cmd
which is invalid.
To do what you want, just use a vector:
typedef struct OperationFlags
{
int bValve_Cmd[2];
}FLAGS_TypeDef;
#define Valve(x) stTest.bValve_Cmd[x]
//....
for(i=1;i<=2;i++)
{
j=Valve(1);
printf("%d",j);
}

Macro replacement is done well before runtime, so you cannot use a variable X containing the value 2 to get stTest.bValve2_Cmd. Instead, you will get stTest.bValveX_Cmd, for which no symbol exists.
You will have to find another way of doing this, such as having an array of values for which you can use X to select:
#define Valve(x) stTest.bValveX_Cmd[x]
typedef struct OperationFlags {
int bValveX_Cmd[2];
} FLAGS_TypeDef;

try this #define Valve(x) (x == 1 ? stTest.bValve1_Cmd : stTest.bValve2_Cmd)
#define Valve(x) (*(&stTest.bValve1_Cmd + (x-1)))
note : It may not work if the environment changes. Also it can not be used in the bit field.
add check
#define Valve(x) (*(&stTest.bValve1_Cmd + (x-1))); \
assert(offsetof(FLAGS_TypeDef, bValve2_Cmd) == sizeof(int))

Related

using function names as functions in a C macro

Suppose i have code like this in my program:
if (!strcmp(current, "sin")) {
pushFloat(sin(x), &operands);
} else if (!strcmp(current, "cos")) {
pushFloat(cos(x), &operands);
} else if (!strcmp(current, "tan")) {
pushFloat(tan(x), &operands);
} else if (!strcmp(current, "ctg")) {
pushFloat(1. / tan(x), &operands);
} else if (!strcmp(current, "ln")) {
pushFloat(log(x), &operands);
} else if (!strcmp(current, "sqrt")) {
pushFloat(sqrt(x), &operands);
}
There are function names such as "sin" or "cos" saved in the current char array
Instead of using this long if block, or replacing it with an even longer switch block, i wanted to write a simple macro like this: #define PUSHFUNC(stack, func, value)(pushFloat(func(value), &stack)) and call it like this PUSHFUNC(operands, current, x)
Doing it this way creates an error "current is not a function or function pointer". I initially thought macros are just text replacement, so if i force a string that is equal to an actual function into a macro, it would expand to the function itself, but looks like i was wrong. Is there a way to achieve what i want using a macro, or should i just write a map block?
I initially thought macros are just text replacement,
That's your problem: macros are just text replacement. So if you have:
#define PUSHFUNC(stack, func, value) (pushFloat(func(value), &stack))
And you write:
PUSHFUNC(operands, current, x)
You get:
(pushFloat(current(value), &operands))
And indeed, you have no function named current. Macros are expanded before your code compiles; the preprocessor has no knowledge of the content of your variables.
If you really want to avoid a long chain of if statements, you could implement some sort of table lookup:
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <math.h>
typedef double (*floatop)(double x);
typedef struct {
char *name;
floatop operation;
} entry;
double ctg(double);
entry opertable[] = {
{"sin", sin},
{"cos", cos},
{"tan", tan},
{"ctg", ctg},
{"sqrt", sqrt},
{NULL, NULL},
};
double ctg(double x) {
return 1. / tan(x);
}
floatop findop(char *name) {
int i;
for (i=0; opertable[i].name; i++) {
if (strcmp(opertable[i].name, name) == 0) {
return opertable[i].operation;
}
}
}
int main() {
float x = 4;
printf("sin(%f) = %f\n", x, findop("sin")(x));
printf("sqrt(%f) = %f\n", x, findop("sqrt")(x));
printf("tan(%f) = %f\n", x, findop("tan")(x));
printf("ctg(%f) = %f\n", x, findop("ctg")(x));
}
...but this requires that all of your functions take the same arguments, so for things like ctg you would need to add a helper function. You also need to decide if the increased complexity of the table lookup makes sense: it really depends on how many different operation names you expect to implement.
The output of the above code is:
sin(4.000000) = -0.756802
sqrt(4.000000) = 2.000000
tan(4.000000) = 1.157821
ctg(4.000000) = 0.863691
Is there a way to achieve what i want using a macro, or should i just write a map block?
I would recommend using an enum containing symbols for all the functions you might want to call, and using that in a switch-case block, instead of comparing a bunch of strings. Here's a very brief sample that only uses some of the functions you refer to...
enum which_func { SIN, COS, TAN, };
enum which_func which = SIN;
switch (which) {
case SIN:
pushFloat(sin(x), &operands);
break;
case COS:
pushFloat(cos(x), &operands);
break;
case TAN:
pushFloat(tan(x), &operands);
break;
default:
assert(false); // shouldn't be reachable if enum value is well-defined
}
This version will be easier to maintain in the long run, more efficient to execute and possibly more robust to logic errors (there are some compiler warnings that you can enable which will warn you if you're not handling all enum values, which can help you catch missed cases in your logic).
To add to what other answers said, what you can do is to make a macro that expands to the "basic block" of your if chain, avoiding some repetitions thanks to the stringizing operator:
#define HANDLE_FN_EXPR(fn, expr) \
else if(!strcmp(current, #fn)) \
pushFloat((expr), &operands)
#define HANDLE_FN(fn) \
HANDLE_FN_EXPR(fn, fn(x))
Then you can do
if(0);
HANDLE_FN(sin);
HANDLE_FN(cos);
HANDLE_FN(tan);
HANDLE_FN_EXPR(ctg, 1./tan(x));
HANDLE_FN(ln);
HANDLE_FN(sqrt);
Macros do in fact do text replacement. Given your macro definition, this:
PUSHFUNC(operands, current, x)
expands to this:
(pushFloat(current(x), &operands))
So as you can see, the text that is being replaced is the name of the variable, not the text that it contains.
And even if this did work as you expected, it wouldn't be able to properly handle the 1. / tan(x) case.
This means there isn't really a better way to do what you want.
Why not create some objects for each function type? I know, this is C not C++, but the idea will still work. First, create the function object type:-
typedef struct _Function
{
char *name;
float (*function) (float argument);
} Function;arg
And now create an array of function objects:-
Function functions [] =
{
{ "sin", sin },
{ "cos", cos }
// and so on
};
where the functions are defined:-
float sin(float x)
{
return 0; // put correct code here
}
float cos(float x)
{
return 0; // put correct code here
}
Finally, parse the input:-
for (int i = 0; i < sizeof functions / sizeof functions[0]; ++i)
{
if (strcmp(functions[i].name, current) == 0)
{
pushFloat(functions[i].function(arg)); // add operands!
break;
}
}
I find using enums for stuff like this very hard to maintain! Adding new functions means going through the code to find cases where the enum is used and updating it prone to errors (like missing a place!).
All because it's not C++, doesn't mean you can't use objects! It's just there's no language support for it so you have to do a bit more work (and, yeah, there are features missing!)

C macro expansion of a function pointer based on for loop incrementor

I have a function that takes a pointer to a function as a parameter.
This function get's called within a for loop due to the similar nature of the names of the function pointer I use a macro to expand the name into the function. IT looks something like this:
void fill(int, int(*funcbase)(int));
int funcbase0(int);
int funcbase1(int);
int funcbase2(int);
int funcbase3(int);
/// all the way through funcbase31
#define FILL_(num) fill(num, funcbase##num)
#define FILL(num) FILL_(num)
for(int i = 0; i < 32; i++)
FILL(i);
I would like this to call fill for 0,1,2,... and funcbase0, funcbase1, funcbase2,... , but it calls fill with the second parameter of "funcbasei" It does not expand i every time.
Is what I'm trying to do possible? What compiler would I need to try? (I'm using gcc 4.9.3)
What you are trying to do is not possible with a macro because macros are expanded at compile time, well before the runtime and loops start running.
However, you can easily do this with a for loop on an array of function pointers:
typedef int(*funcbase_t)(int);
funcbase_t fbases[] = {
funcbase0, funcbase1, funcbase2, funcbase3, ...
};
Now you can run your loop on fbase array:
for(int i = 0; i < 32; i++)
fbases[i](i);
You can use the preprocessor to do this, by recursively splitting the interval into parts and calling it for each one. Or use the pre-built version in boost:
#include <boost/preprocessor/repetition/repeat.hpp>
// and in code
#define FILL_(num) fill(num, funcbase##num)
#define FILL(num) FILL_(num)
#define MACRO(z, n, text) FILL_(n);
BOOST_PP_REPEAT(4, MACRO, 0);

Having Compiling trouble with definition function in another header

So I was wondering why I am getting the following error:
Error 1 undefined reference to `MIN_COUNTER' C:\Users\Wyatt
Crosby\Dropbox\Atmel
Studio\ReflowController\ReflowController\ReflowController\Debug/.././ReflowController.c 146 1 ReflowController
When in PID.h I have:
#ifndef PID_H
#define PID_H
#define LCD_SCREEN_SIZE 16
#define MAX_COUNTS 180
#define OVEN_MAX_TEMP 260
#define OVEN_MIN_TEMP 0
#define MIN_COUNTER(x,a) tempLookupArray[x] < a ? x : MIN_COUNTER(x+1,a)
#define FIND_COUNTER(a) a <= OVEN_MIN_TEMP ? MAX_COUNTS : MIN_COUNTER(0,a)
const float tempLookupArray[MAX_COUNTS];
...
Where tempLookupArray is define further in PID.c:
const float tempLookupArray[MAX_COUNTS] = {
260.00,
260.00,
260.00,
259.99,
259.98,
259.96,
...
And in ReflowController.c I include PID.h and write:
TriggerCounter = FIND_COUNTER(PIDgain);
Where PIDgain is local and of type 'float', and TriggerCounter is global and of type 'volatile int'
It seems to be the fact that I am trying to call MIN_COUNTER from inside MIN_COUNTER and doesn't have any sort of prototype for it yet (if it were a function) . . .
Any thoughts from you smart guys out there?
Thanks!
After the preprocessor has gone through your code,
TriggerCounter = FIND_COUNTER(PIDgain);
becomes
TriggerCounter = PIDgain <= 0 ? 180 : tempLookupArray[0] < PIDgain ? 0 : MIN_COUNTER(0+1,PIDgain);
At that point, the preprocessor hands the code to the compiler and linker who look for a method called MIN_COUNTER but can't find one. The preprocessor doesn't work recursively in a case like that. Imagine if it did: The code you wrote would send the compiler in an infinite loop; it would need to expand MIN_COUNTER and to do that, it needs to expand another MIN_COUNTER and so on...
Try using actual functions instead of macros
int min_counter(int x, float a) {
return tempLookupArray[x] < a ? x : min_counter(x+1,a);
}
int find_counter(float a) {
return a <= OVEN_MIN_TEMP ? MAX_COUNTS : min_counter(0,a);
}
In addition to recursing properly, it will also avoid some of the caveats of macros (For example, FIND_COUNTER(i++) would increment i multiple times, whereas find_counter(i++) wouldn't)

Force function to accept specific definitions only?

I would like to force a functions parameters to accept only specific definitions. For example, consider #define OUTPUT 1, #define INPUT 0 and void restrictedFunction(int parameter); .
How would I force restrictedFunction(int parameter) to accept only OUTPUT or INPUT?
I would also like to take into consideration that another definition may have the same value, for example, #define LEFT 1 and #define RIGHT 0.
So in this case I would like restrictedFunction(int parameter) to be able to accept only OUTPUT and INPUT specifically.
typedef enum { INPUT = 0, OUTPUT = 1 } IO_Type;
void restrictedFunction(IO_Type parameter) { ... }
It doesn't absolutely force the use of the values (the compiler will let someone write restrictedFunction(4)), but it is about as good as you'll get.
If you truly want to force the correct type, then:
typedef enum { INPUT = 0, OUTPUT = 1 } IO_Type;
typedef struct { IO_Type io_type } IO_Param;
void restrictedFunction(IO_Param parameter) { ... }
In C99 or later, you could call that with:
restrictedFunction((IO_Param){ INPUT });
This is a compound literal, creating a structure on the fly. It is not entirely clear that the structure type really buys you very much, but it will force the users to think a little and may improve the diagnostics from the compiler when they use it wrong (but they can probably use restrictedFunction((IO_Param){ 4 }); still).
What this means is that your restrictedFunction() code should be ready to validate the argument:
void restrictedFunction(IO_Type io_type)
{
switch (io_type)
{
case INPUT:
...do input handling...
break;
case OUTPUT:
...do output handling...
break;
default:
assert(io_type != INPUT && io_type != OUTPUT);
...or other error handling...
break;
}
}
You could use an enum.
typedef enum TrafficDirection { INPUT = 0, OUTPUT = 1 } TrafficDirection;
restrictedFunction(TrafficDirection direction);
of course, this isn't perfect. You can still pass any int to it as long as you use a cast.
restrictedFunction((TrafficDirection) 4);
You don't get quite as much protection as you might like, but you can do:
enum func_type { INPUT, OUTPUT };
void restrictedFunction( enum func_type parameter );
You can use a wrapper to validate the argument:
#define restrictedFunction(x) do { \
static_assert((x) == INPUT || (x) == OUTPUT); \
assert(!strcmp(#x, "INPUT") || !strcmp(#x, "OUTPUT")); \
restrictedFunction(x); \
} while(0)
Notes:
This assumes restrictedFunction() returns a void. If it returns a value which you actually use, you'll need something like gcc's compound statement http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html. Or--better--you can use BUILD_BUG_ON_ZERO (see What is ":-!!" in C code?), which I keep forgetting about, because it doesn't seem to work with C++.
The do ... while(0) is to "swallow the semi-colon"; not really relevant here.
static_assert() is a compile-time assert; there are many variants available. Here is a link to one, https://stackoverflow.com/a/9059896/318716, if you don't have your own handy.
assert() is the standard run-time assert.
With gcc 4.1.2, and my version of static_assert(), you can replace the run-time assert() with a compile-time assert when the two !strcmp()'s are replaced with ==; see example below. I haven't tested this with other compilers.
x is only used once in the macro expansion, since the first four references are only used at compile-time.
When your actually define your function, you'll have to add parentheses to disable the macro expansion, as in:
void (restrictedFunction)(int x){ ... }
Also, if your code has a special case (whose code doesn't?) where you need to call restrictedFunction() with the argument foo, you'll need to write:
(restrictedFunction)(foo);
Here is a complete example, which puts a wrapper around the standard library function exit():
#include <stdlib.h>
#define CONCAT_TOKENS(a, b) a ## b
#define EXPAND_THEN_CONCAT(a,b) CONCAT_TOKENS(a, b)
#define ASSERT(e) enum{EXPAND_THEN_CONCAT(ASSERT_line_,__LINE__) = 1/!!(e)}
#define ASSERTM(e,m) enum{EXPAND_THEN_CONCAT(m##_ASSERT_line_,__LINE__)=1/!!(e)}
#define exit(x) do { \
ASSERTM((x) == EXIT_SUCCESS || (x) == EXIT_FAILURE, value); \
ASSERTM(#x == "EXIT_SUCCESS" || #x == "EXIT_FAILURE", symbol); \
exit(x); \
} while(0)
int main(void) {
exit(EXIT_SUCCESS); // good
exit(EXIT_FAILURE); // good
exit(0); // bad
exit(3); // doubly bad
}
If I try to compile it, I get:
gcc foo.c -o foo
foo.c: In function 'main':
foo.c:17: error: enumerator value for 'symbol_ASSERT_line_17' is not an integer constant
foo.c:18: warning: division by zero
foo.c:18: error: enumerator value for 'value_ASSERT_line_18' is not an integer constant
foo.c:18: error: enumerator value for 'symbol_ASSERT_line_18' is not an integer constant

Can a macro be used for read-only access to a variable?

Can you define a macro that accesses a normal variable, but in a read-only fashion (other than defining it as a call to a function)? For example, can the VALUE macro in the following code be defined in such a way that the dostuff() function causes a compile error?
struct myobj {
int value;
}
/* This macro does not satisfy the read-only requirement */
#define VALUE(o) (o)->value
/* This macro uses a function, unfortunately */
int getvalue(struct myobj *o) { return o->value; }
#define VALUE(o) getvalue(o)
void dostuff(struct myobj *foo) {
printf("The value of foo is %d.\n", VALUE(foo)); /* OK */
VALUE(foo) = 1; /* We want a compile error here */
foo->value = 1; /* This is ok. */
}
Ok, I came up with one:
#define VALUE(o) (1 ? (o)->value : 0)
If the variable is always numeric, this works:
#define VALUE(x) (x+0)
or in the context of your example,
#define VALUE(x) (x->value+0)
See §6.5.17 in the C standard (C99 & C1x): “A comma operator does not yield an lvalue.”
#define VALUE(x) (0, x)
(Not portable to C++.)
Try
#define VALUE(o) (const int)((o)->value)
Is this a puzzle or is it an engineering task?
If it's an engineering task, then there are better ways to get opacity of structures in C. In this blog article, I wrote a decent enough description of how to do that in C.

Resources