I want to know which macro gets replaced first in the following code
#define A 100
#define B 200
#define C(A,B) A+B
here when we use C, then evaluation will be from left to right or right to left. That is B gets the value first or A gets the value first
i gave this example just to make things look simple, may be i was wrong. the actual thing i want to ask is, if A and B also take arguments and have the scope of expansion, then which one would expand first
I'm not sure what you mean. There's never a point where you can "see" half a result of the preprocessor; the entire input file is preprocessed, then handed over to the compiler.
I think that the names for the macro arguments will never also be replaced as if they were stand-alone symbols.
I tried it, and this program:
#include <stdio.h>
#define A 100
#define B 200
#define C(A, B) A + B
int main(void) {
printf("A=%d\nB=%d\nC(1,2)=%d\n", A, B, C(1,2));
return 0;
}
prints
A=100
B=200
C(1,2)=3
So, C(1,2) expands to 1 + 2, the definitions of A and B don't matter.
Of course I must say that I find the above very bad practice, since it's quite confusing. Never use all-caps names for macro arguments, since macros and preprocessor symbols tend to use such names.
Related
cpp_magic extends what can typically be done with the C Preprocessor.
(It's a single header file and is on GitHub, here.)
The IF_ELSE(cond)(<true_result>, <false_result>) is a super useful macro!
How can expressions be evaluated in the cond clause?
It doesn't appear to work as advertised: with expressions in the cond part.
The following returns 10:
int greater = IF_ELSE(10 > 20)(10, 20);
The macro always returns the first argument, unless it is a simple 0 or 1.
Is the c argument (condition) a misnomer (and is really ust a simple value)?
I also tried this, according to a suggestion below, but it gives the same result:
#define GREATER(x,y) BOOL(x > y)
int greater = IF_ELSE(GREATER(10,20))(10, 20);
But it also evaluates to 10.
(Note that IF_ELSE already calls BOOL(c) on its argument.)
Has anyone used IF_ELSE with a general preprocessor expression?
Looking at cpp_magic, it looks a bit basic. If you want to evaluate math in the preprocessor using that, you have to basically implement the math yourself using macros. First off the bat, cpp_magic's IF_ELSE macro is defined as follows:
#define IF_ELSE(condition) _IF_ ## condition
That's a dead stop to using it as you prescribe, because this macro's expansion list contains a paste. The way macros expand involves four steps:
Argument substitution (a.s.; 6.10.3.1), where for each mention of a parameter in the macro's replacement list where said parameter is not participating in a paste or stringification, the corresponding argument is fully expanded, and the resulting expansion replaces the mention in the replacement list.
Stringification (6.10.3.2)
Pasting (6.10.3.3)
Rescan-and-further-replacement (r.a.s.r.; 6.10.3.4), where the resulting replacement list is rescanned; during this rescan the macro in question is marked as invalid for further expansion ("painted blue") to avoid recursion.
So in cpp_magic's implementation of IF_ELSE, no matter what you pass in as the condition, it will not do a.s.; instead, it will simply paste to _IF_. E.g., if you call IF_ELSE(BOOL(x)), you would simply get _IF_BOOL(x). You can patch this (but it's ugly, and there's a much much better library... see below) by adding an indirection macro like this:
#define EVAL_IF_ELSE(condition) IF_ELSE(condition)
...so you need at least this. For a greater comparision, you would need to implement greater. Here's a trivial implementation:
#define GLUE(A,B) GLUE_I(A,B)
#define GLUE_I(A,B) A##B
// repeats X N times
#define N_TIMES(N,X) GLUE(N_TIMES_,N)(X)
#define N_TIMES_1(X) X
#define N_TIMES_2(X) X,N_TIMES_1(X)
#define N_TIMES_3(X) X,N_TIMES_2(X)
#define N_TIMES_4(X) X,N_TIMES_3(X)
#define N_TIMES_5(X) X,N_TIMES_4(X)
// pop; technically non-compliant for one parameter
// which I could code around, but this is a simplified
// demo only (and there's a much better way)
#define POP(...) POP_I(__VA_ARGS__)
#define POP_I(X,...) __VA_ARGS__
#define NTH(N,...) GLUE(NTH_,N)(__VA_ARGS__)
#define NTH_1(...) NTH_1_I(__VA_ARGS__,)
#define NTH_1_I(X,...) X
#define NTH_2(X,...) NTH_1(__VA_ARGS__)
#define NTH_3(X,...) NTH_2(__VA_ARGS__)
#define NTH_4(X,...) NTH_3(__VA_ARGS__)
#define NTH_5(X,...) NTH_4(__VA_ARGS__)
#define COMPARE(X,Y) NTH(X,POP(N_TIMES(Y,L)),E,N_TIMES(5,G))
#define GREATER(X,Y) GLUE(GREATER_RESULT_,COMPARE(X,Y))
#define GREATER_RESULT_L 0
#define GREATER_RESULT_E 0
#define GREATER_RESULT_G 1
...so that's a nice start. And this greater works perfectly... for numbers up to 5... so long as you ignore the 1 case. There's a skeleton here for how to do other comparisons, but they would only work up to 5. A demo working up to 20 is shown here.
This shows what you want to do is possible, but it's still a lot of work. Here I'm only showing a way to do a comparison; but everything else you want to do (add, sub, mul, div, etc) also needs an implementation, and each piece is code. If you want to play with it, knock yourself out, but I would recommend for play ditching the C language and just use your preprocessor like I do in the demo.
There is a much, much better way
...and that is to let someone else do all of the work for you. And they have! What you're in effect trying to do has been pulled into the boost preprocessor library. BPP also has add, sub, mul, div, and so on. For BPP's implementation, the saturation is at 255. Here's how you would do your conditional using boost preprocessor:
#include <boost/preprocessor/comparison.hpp>
#include <boost/preprocessor/control.hpp>
BOOST_PP_IF(BOOST_PP_GREATER(10,20),10,20)
...and a demo
Please give me full description....
The first snippet of code has the 'function call' (macro invocation) before the increment operator, and second one has the function call after the increment operator.
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b)++;
printf("%d%d",a,b);
return 0;
}
output:
124
why is 124 returned here
#include <stdio.h>
#define square(x) x*x
int main()
{
int a,b=3;
a=square (b++);
printf("%d%d",a,b);
return 0;
}
output:
125
and 125 here?
The thing to keep in mind is that macros provide simple substitution of preprocessor tokens. In particular, they may evaluate their arguments more than once, and if not guarded by parentheses, they may produce unintended reassociation.
In the first example, we have
a=square (b)++;
This expands to:
a=b*b++;
This is actually undefined behavior, since the b and b++ are unsequenced, and b++ modifies b. In your case, you are seeing 12 and 4 for a and b, so it would seem that the first value of b is picking up the incremented value, so you're getting 4*3, but you can't count on this behavior. The final value of b is 4 since it is incremented once.
In the second example, we have:
a=square (b++);
This expands to:
a=b++*b++;
This is again undefined behavior. In your case, it appears that you're getting 4*3 (or 3*4), but again, you can't count on this behavior. The final value of b is 5 since it is incremented twice, but this too is undefined behavior.
In addition to Tom's answer, which explains what is happening, here is an example of how you could define a macro for squaring a number safely:
#define SQR(x) ( \
{ \
__auto_type x_ = (x); \
\
x_ * x_; \
} \
)
It only has an appearance of x, and therefore it doesn't evaluate it twice. The copy x_ is used instead. Note that variables created in a macro may conflict with other variables created in the function that calls the macro. To avoid name collisions you use special names that shouldn't be used in normal code such as a trailing _.
With this macro, this:
a = SQR(b++);
will be equivalent to this:
a = SQR(b);
b++;
Warning: This works on some compilers as an extension (GCC for example), but it is not standard C.
Another option, if you want standard C, is to use an inline function. It is ok if you want it to work on just one type (there is _Generic in C11, but I never used it, so no idea).
Imagine I want to #define a macro such that it is equal to the current value of another macro (if such a concept exists).
For example:
#include "def_a.h" // defines macro A
#define B A
This defines B to be A. If A later changes definition (i.e., through a redefinition) the value of B also changes (because B expands to A at the point of use, which further expands to the new value of A).
What I'd like is some way to "bake in" the value of A into B so that B just expands to the value of A, not A itself.
For example:
#define A first
#define B BAKE_IN(A)
#undef A
#define A second
#define C BAKE_IN(A)
#undef A
#define A third
// here I want B to expand to first, and C to expand to second
Of course BAKE_IN is not a real thing, but I'm wondering if there is some way to achieve this effect.
Now, I didn't really say what should happen if A itself is defined in terms of other macros, but I'm OK both with "one level of expansion" (i.e., B gets the value of A is expanded, so further macros remain) and also "full expansion" (i.e., A is fully expanded, recursively, as it would be at a point of use).
Macros are never replaced in the body of a #define directive, so there is no way to define a macro as the current value of another macro, except for the limited case of macros whose value is a constant arithmetic expression.
In the latter case, you can use BOOST_PP_ASSIGN_SLOT from the Boost preprocessor library. (Although most of the Boost libraries are C++-specific, the Boost preprocessor library works for both C and C++, and has no dependency on any other Boost component.)
I don't think there is a clean solution. The closest thing that I found is to preserve "stringified" values within char arrays:
#include <stdio.h>
#define BAKE_IN(X, id) BAKE_IN_REAL(X ## _, X, id)
#define BAKE_IN_REAL(X, Y, id) static const char X ## id[] = #Y;
#define BAKE_OUT(X, id) X ## _ ## id
#define A first
BAKE_IN(A, 1)
#define B BAKE_OUT(A, 1)
#undef A
#define A second
BAKE_IN(A, 2)
#define C BAKE_OUT(A, 2)
#undef A
int main(void)
{
printf("%s\n", B); // prints "first"
printf("%s\n", C); // prints "second"
return 0;
}
The idea is that BAKE_IN macro declares object named as e.g. A_1, which holds the current expansion of A.
There are two major limitations:
Every pair of BAKE_IN and BAKE_OUT needs unique id
The expansion is only available in "stringified" form
How are the definitions in C processed? Are they processed in order of line numbers?
For example, will the following statements work?
#define ONE 1
#define TWO (ONE+1)
Could there be any problems with definitions that depend on previous definitions?
Yes, one #define can reference other #define substitutions and macros without any problem.
Moreover, the expression on these constants would remain a constant expression.
Your second expression would be textually equivalent to (ONE+1) replacement in the text, with no limits to the level of nesting. In other words, if you later define
#define THREE (TWO+1)
and then use it in an assignment i = THREE, you would get
i = ((ONE+1)+1)
after preprocessing.
If you are planning to use this trick with numeric values, a common alternative would be to use an enum with specific values, i.e.
enum {
ONE = 1
, TWO = ONE+1
, THREE = TWO+1
, ... // and so on
};
They're processed at point when they're used, so you example and even this
#define TWO (ONE+1)
#define ONE 1
will work.
The best way is to check by yourself:
g++ test.cpp
gcc test.c
For strict compiler check:
gcc test.c -pedantic
And all worked for me!
test.c/test.cpp
#include <stdio.h>
#define A 9
#define B A
int main()
{
printf("%d\n",B);
return 0;
}
The compiler processes the #define-s in the order they were de...fined. After each #define gets processed, the preprocessor then proceeds to process all text after this #define, using it in the state left by this #define. So, in your example:
#define ONE 1
#define TWO (ONE+1)
It first processes #define ONE 1, replacing all further occurunces of ONE with 1. So, the second macro becomes
#define TWO (1+1)
That is how it will be processed and applied by the preprocessor.
The reverse example:
#define TWO (ONE+1)
#define ONE 1
will also work. Why? Well, the preprocessor will take the first #define, scan the code for any occurences of TWO, and replace it with (ONE+1). Then it reaches the second #define, and replaces all occurences of ONE, including those put in place by the previous #define, with 1.
I'd personally prefer the former approach over the latter: it's plainly easier for the preprocessor to handle.
I am trying to solve two Preprocessor related questions but in both programs I am getting results that I am not able to figure out how. Below is my program:
#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);
printf("Result:%f\n",a);
return 0;
}
According to me, the output of this programme should be -25.000 but I am getting -100.000.
And in second program:
#define FUN(i,j) i##j
int main()
{
int val1 = 10;
int val12 = 20;
clrscr();
printf("%d\n",FUN(val1,2));
getch();
}
Output should be 102 but I am getting 20;
why is it so?
#define SQUARE(x) x*x
should be
#define SQUARE(x) ((x)*(x))
Indeed, without the parentheses, 2*(s-u*t)/SQUARE(t) is expanded as
2*(s-u*t)/t*t
which is interpreted as
(2*(s-u*t)/t)*t
As to your second problem, FUN(val1,2) will get expanded as val12 per the semantics of the ## operator. It is still not clear what your intent is: the printf line will be understood as
printf("%d\n", val12);
which will print 20.
the first one:
a=2*(s-u*t)/SQUARE(t);
after replacing the define we get:
a=2*(s-u*t)/t*t;
now, since we don't have () in the definition of SQUARE we get:
a=2*(10-30*2)/2*2; --> a=2*(-50)/2*2; --> a=-100/2*2; --> a=-50*2; --> a=-100
if you want to get -25 you should define SQUARE(x) as (x*x).
Edit : add explanation regarding the second example.
printf("%d\n"FUN(val1,2));
once again, we first should replace the define (reminder: ## "concatenates" the string of the define - I can't find the perfect words in order to explain it so just take a look at the example...):
printf("%d\n",val12); [note: the comma (,) is missing - so it won't compile.]
since the value of val12 is 20 that's what you'll get.
the point of those 2 examples is to remember that we should always deal with the defines first (since in "real life" the compiler (or pre-processor) does it before the run time)
I hope it helps..
For the first case,
a=2*(s-u*t)/SQUARE(t);
would translate to
a=2*(s-u*t)/t*t;
at compile time. This is a common mistake made with preprocessors.
i know i am late, but i am having the perfect answer.
in c # at define is used to call the text as it is in the function parameter,
example, #define hai(s1) printf("%s=%s",#s1,s1);
in main: i am calling as hai(tom); tom was initialized as "india" string.
the output for this is tom=india, the calling string tom is printed by help of #.
similarly ## is used to take the text from function argument and join them and return the value of the joined identifier.
the above program has two argument va1 and 2. passed to i and j. then va1 and 2 is joined. and form va12.
va12 is the identifier available with value 20. that's why 20 is returned.