Why does the following code report an Lvalue required error?? And how can we write a macro that receives an array and the number of elements in the array as arguments and then print out the elements of the array??
#define arr(b) printf("%d",b++);\
printf("%d",b);
int main()
{
arr(5);
}
If you expand the macro, you get the following:
int main()
{
printf("%d",5++);
printf("%d",5);
}
You cannot postincrement the constant 5, so you get an error.
Remember, macros aren't functions. If you want it to act like a function, simply make a function:
void arr(int b) {
printf("%d",b++);
printf("%d",b);
}
Because part of that macro expands to 5++, which is not valid C. Consider using b+1 instead of b++.
The first l in lvalue stands for left.
Only left values can be assigned.
when you write x ++ you mean x = x + 1 (also you get a value from it).
So the problem is it does not make sense to write 5 = 5 + 1
maybe you would like to do this:
int x = 5;
arr(x);
Related
I' m learning Macro in c,
I wrote a small function in macro to swap number, but passed the value as 'pass by value' since i didn't use address of operator (&) before the variable in the argument, But when i ran the program. The value got swaped. You can refer the code and mention me where i got wrong in understanding?
#include<stdio.h>
#include<conio.h>
#define swap(a,b) a = a+b;b = a-b; a = a-b;
int main()
{
int x = 5, y = 10;
swap(x,y);
printf("%d %d\n",x,y);
getch();
return 0;
}
Do the arguments acts as pass by reference, when using it in macro?
C doesn't have pass-by-reference. And that's not what's happening here anyway. When a macro is "called", the preprocessor replaces the call-site with the body.
With your example, the invocation
swap(x,y);
is replaced by
x = x+y;y = x-y; x = x-y;;
This last line is what the actual parser of the compiler sees.
Many compilers have options to stop after the preprocessing step. I suggest you use that to see exactly what the preprocessor have done.
I also hope you start to see how macros can "break" your code.
For example if the code was
if (some_condition)
swap(x,y);
Then it would be expanded to (with some reformatting)
if (some_condition)
x = x+y;
y = x-y;
x = x-y;
;
This is clearly not what was intended and will not work.
You also have the case when the arguments to the macro are not simple variables, but expressions. Like
swap(x+1,y*2)
While would be replaced by
x+1 = x+1+y*2;y*2 = x+1-y*2; x+1 = x+1-y*2;;
This also would not work.
I write a lot of code like this
int x = 0;
//in some loop
x++;
if (x > 10) {
x = 0;
//call some function
}
How could I extract this into a function, or a macro, where I can combine the decrementing (or incrementing), the value to exceed (or go under), the reset value (0 in this case) and the function call?
EDIT:
I'd love to do something like (pseudocode)
cycle_counter(x, ++, <10, 0, myfunc);
#define SATURATE_ADD(x, max, inc, reset) ((x) = (x) > (max) ? (reset) : (x) + (inc))
and in your example:
int x = 0;
SATURATE_ADD(x, 10, 1, 0);
And if you want to call some function, just add a function parameter that you will call in your macro.
I tried to create a function to solve the problem similar to the function in pseudocode
void cycle_counter(int *px, char operatorr, int max, int init, void (*p)())
{
*px=init;
//in some loop
operatorr?(*px)++:(*px)--; //if the operator is 0 we usee -- otherwise ++
((*px)>max)?((*px)=0,p()):0; // This line replaces the if statement in your
// code and the callback
}
so here we have used the pointer named px which is pointing to x so it can keep the changes
The operator operatorr is a boolean which takes the value 0 for -- and ++ otherwise
max is an integer that will be provided for comparison. In your example it will be 10
init is for the initialisation of the integer pointed by the pointer px
Finally p refers to a pointer to function
Now if you want to call this function in the main function you will proceed like that
cycle_counter(px, 1, 10, 0, myfunc);
with px is
int x;
int *px=&x;
There are some exceptions not treated but I've jsut tried to make the difficult part which treats the pointers to functions. The other part (not done > and >=) is easy you can make the ternary operator even more complicated to handle all the cases but you will probably get a lovely line which can be considered as an obfuscated line ;)
I'm attempting to define a macro that allows me to pass in 2 numbers as well as an operator. I want the macro to carry out the specified operation on the two numbers and return the result.
My definition is:
#define GENERAL_OP(x,y,op) ((x) op (y))
which works fine when I call
int result = GENERAL_OP(1, 2, -);
but as soon as I try to pass it a character (which is what I actually need to do in my
generalized function that calls the macro) as in the following example:
void Evaluate(char op)...
int result = GENERAL_OP(1, 2, op);
void Evaluate(char op)...
int result = GENERAL_OP(1, 2, op);
Macro replacement is done before compile time, but the argument of Evaluate is only available at runtime, so the macro expansion leads to
int result = ((1) op (2));
there, and op is not a token that can appear there (probably an undeclared identifier).
Preprocessor operates at compile-time, you can't use the value of op inside your macro.
I see what you're going for... it's sort of like trying to unstringify. I'm pretty sure it can't work the way you want it to. Your best bet would be to do something like:
void Evaluate(char op, int x, int y)
{
int result;
if(op == '-')
GENERAL_OP(x, y, -);
...
But that doesn't make it very "general"...
As I know in C, passing of actual parameters of a function evaluation starts from rightmost and directed to left.
What is the case for a macro definition with parameter? I made a code to make the sense clear but output confused me...
Here is the code.,
#define parsing(a,b) a*b
int parsefun(int a, int b)
{
return a*b;
}
int main()
{
int i=10;
printf("%d\n",parsing((i++),i));
i=10;
printf("%d\n",parsing(i,(i++)));
i=10;
printf("%d\n",parsefun((i++),i));
i=10;
printf("%d\n",parsefun(i,(i++)));
system("PAUSE");
return 0;
}
This code outputs,
100
100
100
110
I hoped same output for macros as function. But where is the crucial point here?
parsing of actual parameters of a function starts from rightmost and directed to left
I think you mean "evaluation" rather than "parsing". But that's not true, the C standard does not specify an order.
So the behaviour you're getting for the functions is unspecified by the C standard.
I hoped same output for macros as function
Macro arguments are not evaluated, they're simply substituted. So you end up with this:
int i=10;
printf("%d\n", (i++) * i);
i=10;
printf("%d\n", i * (i++));
After which, you're simply seeing undefined behaviour, as explained in this question: Why are these constructs (using ++) undefined behavior?.
#include<stdio.h>
#include<conio.h>
#define PROD(x) (x*x)
void main()
{
clrscr();
int p=3,k;
k=PROD(p+1); //here i think value 3+1=4 would be passed to macro
printf("\n%d",k);
getch();
}
In my opinion, the output should be 16, but I get 7.
Can anyone please tell me why?
Macros are expanded, they don't have values passed to them. Have look what your macro expands to in the statement that assigns to k.
k=(p+1*p+1);
Prefer functions to macros, if you have to use a macro the minimum you should do is to fully parenthesise the parameters. Note that even this has potential surprises if users use it with expressions that have side effects.
#define PROD(x) ((x)*(x))
The preprocessor expands PROD(p+1) as follows:
k = (p+1*p+1);
With p=3, this gives: 3+1*3+1 = 7.
You should have written your #define as follows:
#define PROD(x) ((x)*(x))
The problem here is that PROD is a macro and will not behave exactly like you intend it to. Hence, it will look like this:
k = p+1*p+1
Which of course means you have:
k = 3+1*3+1 = 7
#define PROD(x) (x*x)
PROD(3+1) is changed by the preprocessor to 3+1*3+1
macro are not function . These are replaced by name
It will be p+1*p+1
This is what compiler is going to see after preprocessors does its job: k= p+1*p+1. When p = 3, this is evaluated as k = 3+(1*3)+1. Hence 7.
This is exactly why you should use functions instead of macros. A function only evaluates each parameter once. Why not try
int prod(int x)
{ return x * x; }
and see the difference!