#define VAL1CHK 20
#define NUM 1
#define JOIN(A,B,C) A##B##C
int x = JOIN(VAL,NUM,CHK);
With above code my expectation was
int x = 20;
But i get compilation error as macro expands to
int x = VALNUMCHK; // Which is undefined
How to make it so that NUM is replaced first and the JOIN is used?
You can redirect the JOIN operation to another macro, which then does the actual pasting, in order to enforce expansion of its arguments:
#define VAL1CHK 20
#define NUM 1
#define JOIN1(A, B, C) A##B##C
#define JOIN(A, B, C) JOIN1(A, B, C)
int x = JOIN(VAL,NUM,CHK);
This technique is often used with the pasting and stringification operators in macros.
Related
I am trying to create a program that uses macros for determining the mid-range for three values. The midrange is defined as:
midrange(a, b, c) = (min(a, b, c) + max(a, b, c)) / 2
For example:
midrange(3, 10, 1) = (min(3, 10, 1) + max(3, 10, 1)) / 2
= (1 + 10) / 2
= 11 / 2
= 5.5
I am still new to programming, and I am not sure if the syntax I am using for macro definitions is correct. My first question is, can I define a macro in the main function? My second question, should I use curly braces, normal parenthesis, or nothing at all for the body of the macro, that is, the replacement list?
This is what my program looks like for calculating the midrange of three integer values:
#include <stdio.h>
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}
int main(){
//scans the three values
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
int min = MIN(MIN(a, b), c);
int max = MAX(MAX(a, b), c);
//defines new macro for calculating the midrange
//is this allowed/correct formatting and syntax?
#define MIDRANGE((min + max) / 2);
/* initializes variable mrange to equal to the value returned
function-like macro, MIDRANGE */
double mrange = MIDRANGE((min + max) / 2);
printf("The mid-range is: %lf", mrange);
return 0;
}
The reason why I declared the variable mrange as a double is because I want the value of the MIDRANGE macro to be precise, meaning that it will keep the decimal places after the division by 2 in the equation.
Any help is appreciated:)
You can declare a macro anywhere in the code, but unless you have a very specific reason to restrict its usage to a function, it typically appears in the beginning of the .c file or in a .h file.
Macros work by substitution. So if you have something similar to the following:
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
int main(void)
{
int min = MIN(MIN(a, b), c);
}
It will be preprocessed into:
int min = {({(a) < (b) ? (a) : (b);}) < (c) ? ({(a) < (b) ? (a) : (b);}) : (c);};
You can see this by yourself, if you are using GCC, with the command gcc -E source.c. This is obviously not what you wanted, and it will give you a compilation error.
We never use ; at the end of macros, neither put them in blocks. To avoid unexpected operator association with complicated expressions, we guard macro parameters and the whole macro within parentheses.
Your MIN macro should look somewhat like this:
#define MIN(A, B) ((A) < (B) ? (A) : (B))
Finally, there are two things going on with your MIDRANGE macro. First, it should be taking arguments, like you did with MIN. Ideally, it should take three arguments; after all, the whole reason to make it a macro is so that the macro user won't have to calculate everything. Second, if you want the result to be a floating-point number, you should divide by 2.0, not 2.
Here's my first suggestion:
#define MIDRANGE(A, B, C) ((MIN(MIN(A, B), C) + MAX(MAX(A, B), C)) / 2.0)
However, why is this a macro? Make it a function. It's more readable, and easier to mantain. So here's my second suggestion:
double midrange(int a, int b, int c)
{
int min = MIN(MIN(a, b), c);
int max = MAX(MAX(a, b), c);
return (min + max) / 2.0;
}
regarding:
#define MIN(A, B) {(A) < (B) ? (A) : (B);}
#define MAX(A, B) {(A) > (B) ? (A) : (B);}
Lets remember that a macro is nothing more than a direct text replacement.
So looking at:
int min = MIN(MIN(a, b), c);
results in:
int min = { {(a) < (b) ? (a) : (b);} < (c);};
as is obvious from the above,
min is outside the braces '{' and '}' so will be difficult to assign to
the resulting statement contains two spurious ';' characters, which is what the compiler is complaining about
Suggest:
#define MIN( A, B ) ((A) < (B)) ? (A) : (B)
Similar considerations exist for the MAX macro
Can the C macro #define process arithmetic operations in preprocessing?
For example, if I write
#define A 1 + 1
will it be pre-processed to be equivalent to
#define A 2
before compiling?
Furthermore, is it possible to define constants this way without computation overhead:
#define A 1
#define B A + 1
#define C B + 1
...
?
Macros are text replacements (token replacements to be more accurate).
#define A 1 + 1
int main() { printf("%d\n", A); }
will expand to (run gcc -E on the source to get the preprocessor expansion)
int main() { printf("%d\n", 1 + 1); }
(which BTW, is why it's wise to heavily parenthesize in macros (#define A (1+1)), because
you'll usually want A*3 to then be 6 ( (1+1)*3 ) not 4 ( 1+1*3) ) ).
And yes 1+1, seeing as it satisfies the standard's rules for integer constant expressions, is pretty much guaranteed to be processed at compile time and so you can use it in contexts where an integer constant expression is required.
E.g.:
#define A (1+1)
extern char array[A] = { [A-1]='c' } ; //ICE required
struct s { int bitfield:A; }; //ICE required
enum { a = A }; //ICE required
int x = A; //ICE required
int main ()
{
switch(1) case A: puts("unreachable"); //ICE required
}
#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/SQUARE(t); // How is this evaluated ?
printf("Result %f\n",a);
return 0;
}
The output displayed by the compiler is -100.000000. But according to me it should be -25.000000. What should i do to correct it and what is my mistake?
#define does a literal substitution of the string of characters you have defined. So the expression:
a = 2*(s-u*t)/SQUARE(t*t)
Will expand to:
a = 2*(s-u*t)/t*t
Which, given operator order of evaluation, will evaluate as:
a = (2*(s-u*t)/t)*t
Not what you want. You probably really want a = 2*(s-u*t)/(t*t) so you should have:
#define SQUARE(x) (x*x)
Or even better, as #Jongware points out, since x itself could be an expression:
#define SQUARE(x) ((x)*(x))
That way, expressions like, SQUARE(a+b) will evaluate properly as ((a+b)*(a+b)), not (a+b*a+b).
Also as pointed out in comments, you need to beware of macro expression results when you have side effects in your arguments. For example, what does SQUARE(x++) do, and what is the value of x when it is done? In this case, it would give (x++)*(x++), with the value of x being post incremented twice and results may be undefined behavior (depends upon order of post increment in this case).
The preprocessor is a text replacement. So your expression becomes:
a=2*(s-u*t)/t*t;
* and / have equal precendence, so 2*(s-u*t) gets divided by t then multiplied by t.
Explanation:
The macro function SQUARE(x) x*x calculate the square of the given number 'x'.
Step 1: float s=10, u=30, t=2, a; Here the variable s, u, t, a are declared as an floating point type and the variable s, u, t are initialized to 10, 30, 2.
Step 2: a = 2*(s-u*t)/SQUARE(t); becomes,
=> a = 2 * (10 - 30 * 2) / t * t; Here SQUARE(t) is replaced by macro to t*t .
=> a = 2 * (10 - 30 * 2) / 2 * 2;
=> a = 2 * (10 - 60) / 2 * 2;
=> a = 2 * (-50) / 2 * 2 ;
=> a = 2 * (-25) * 2 ;
=> a = (-50) * 2 ;
=> a = -100;
Step 3: printf("Result=%f", a); It prints the value of variable 'a'.
Hence the output of the program is -100
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/t*t; // SQUARE(t) is defined as t*t so it is
// what is placed here instead of SQUARE(t)
Which is probably not what you want since /t*t==1.
SOLUTION:
#include<stdio.h>
#define SQUARE(x) ((x)*(x))
then:
#include<stdio.h>
#define SQUARE(x) x*x
int main(){
float s=10,u=30,t=2,a;
a=2*(s-u*t)/((t)*(t)); // again, exactly as in #define SQUARE(t)
So I was wondering when is to use
#define xxx (yyy)
vs
#define xxx yyy
My project includes a files that has its own defines such at AD0_ADMD_CT if I wanted to redefine them would I need to use (AD0_ADMD_CT) or just AD0_ADMD_CT in the define or not?
AD0_ADMD_CT is a defined as
#define AD1_ADMD_CT (IO_AD1.ADMD.bit.CT)
So it would be either
#define AD0_COMPARETIME (AD0_ADMD_CT)
or
#define AD0_COMPARETIME AD0_ADMD_CT
There is no difference in both. In first case XXX is replaced by yyy and by (yyy) is second case. The convention to use brackts is to avoid logical errors that may occur. For example you define addition function as:
#define f(N) N+N
int a = f(5)*f(5)
Expected value is 10*10 = 100 , but output is 35 because at compile time is becomes
int a = 5+5*5+5, so using operator preference rule, output changes.
So parenthesis avoid these type of errors.
By adding parentheses, you are forcing the argument inside the parentheses to be evaluated before the rest of the macro body, so if you had
#define MULT(x, y) (x) * (y)
// now MULT(3 + 2, 4 + 2) will expand to (3 + 2) * (4 + 2)
It does not appear to affect your current case unless there is more to your macros.
It's very important if you have operators in your macro. For example:
#define ADD(x,y) x + y
ADD(1,2) * 3 /* Should be 9, is 7 */
Should be:
#define ADD(x,y) (x + y)
ADD(1,2) * 3 /* 7 */
These precedence problems also apply for the arguments, as #Gi Joe says, and need to be wrapped in parens for precedence.
However, for a macro like:
#define MAGICNUM 3
It doesn't matter.
An important thing to remember is that the preprocessor simply expands macros. For example, if you had the following lines:
#define AD0_COMPARETIME_1 (AD0_ADMD_CT)
#define AD0_COMPARETIME_2 AD0_ADMD_CT
num_1 = AD0_COMPARETIME_1;
num_2 = AD0_COMPARETIME_2;
After the first expansion you'd have this:
num_1 = (AD0_ADMD_CT);
num_2 = AD0_ADMD_CT;
And after the second expansion you'd have this:
num_1 = ((IO_AD1.ADMD.bit.CT));
num_2 = (IO_AD1.ADMD.bit.CT);
A problem may arise, as stated in other answers, when an expression is expanded.
Given:
#define f(x, y) (x+y)
#define g(x, y) (x*y)
#define A 1, 2
#define B 2, 3
int main() {
int a = f(A);
int b = g(A);
int c = f(B);
int d = g(B);
}
which does not work,
how can I make it work? The basic idea is that I have one list of arguments that I want to pass to two different macros, without repeating the list of long arguments every time.
Is there a way to do this? [You're welcome to modify f & g; you're even welcome to modify A & the way I call the macros. The only requirements are:
1) the arguemnt list can only appear once
2) it can't be hard coded ... so that I can call the macros with different arguments
If you're solution doesn't quite work but 'almost works' (for you definition of almost), I'd like to hear it too, perhaps I can fudge it to work.
Thanks!
Edit: f & g must be macros. They capture the symbol names and manipulate them.
You could do this:
static int f(int x, int y) { return (x+y); }
static int g(int x, int y) { return (x*y); }
#define A 1, 2
#define B 2, 3
If you were using a C compiler that supported a nonstandard inline directive, you could eliminate the overhead of a function call. And if you were using C++,
template<T> T f(T x, T y) { return (x+y); }
template<T> t g(T x, T y) { return (x*y); }
#define A 1, 2
#define B 2, 3
which would work roughly the same as your intended C macro solution.
If f and g must be macros, there isn't any way with the C preprocessor to pass multiple arguments to the macros without an actual comma appearing at the invocation site. In order to do that, you would have to add a pre-preprocessor level above the C preprocessor.
If you were using C99, you can use the compound initialiser syntax to do this by passing multiple arguments as a single array:
#define f(a) (a[0]+a[1])
#define g(a) (a[0]*a[1])
#define A ((int[]) {1, 2})
#define B ((int[]) {2, 3})
GCC supports this compound literal syntax in both C89 and C++ mode.
EDIT: A version that works with unmodified A and B
#define f(x, y) (x+y)
#define g(x, y) (x*y)
#define A 1, 2
#define B 2, 3
#define APPLY2(a, b) a b
#define APPLY(a, b) APPLY2(a, (b))
int main(int argc, char* argv[])
{
int x= APPLY(f, A);
int y= APPLY(f, B);
int z= APPLY(g, A);
int d= APPLY(g, B);
return 0;
}
Maybe this is what you want:
#include<iostream>
using namespace std;
#define A 1, 2
template <typename T>
inline T f(T a, T b) { return a + b; }
int main()
{
cout << f(A) << endl;
return 0;
}