Can someone explain the output of this program -
#include<stdio.h>
#include<conio.h>
#define FUDGE(k) k+3.14159
#define PR(a) printf(#a" = %d\t ",(int)(a))
#define PRINT(a) PR(a);putchar('\n')
int main()
{
int x=2;
PRINT(x*FUDGE(2));
printf(\n);
PR(x*FUDGE(2));
return 0;
}
OUTPUT -
x*2+3.14159 = 7
x*FUDGE(2) = 7
Why is FUDGE(2) getting printed in second and not in the first statement.
The # operator is strange. It works before expanding the parameter.
So when calling PR(x*FUDGE(2)), # is applied to x*FUDGE(2) before FUDGE is expanded.
However, in PRINT(x*FUDGE(2)), FUDGE is expanded before passing it on to PR. When PR applies # to it, it has already been expanded.
Because in the first you use PRINT which expands the argument when it "calls" PR.
Related
I am trying to use Boost.Preprocessor to do some compile-time work. I want to index a table using values that are computed in other macros. When I try I get the following error: "concatenation with '(' in macro 'BOOST_PP_BOOL_I' does not create a valid token."
This is the simplest code that produces the issue.
#define MY_TABLE (0, (1, BOOST_PP_NIL))
#define MY_INDEX_FUNCTION(x) (x)
void func() {
int y = BOOST_PP_LIST_AT(MY_TABLE, MY_INDEX_FUNCTION(0));
}
It is pretty easy to determine that removing the parens in MY_INDEX_FUNCTION resolves the issue in this case. My actual code uses a much more complex function to calculate the table index in a much larger table.
Is there something that I can do or change that would fix this such that the parens and more complex macros don't cause problems?
The second parameter of BOOST_PP_LIST_AT takes an index/integer. It works with tricky preprocessor hacks under the hood. The parameter(expanded) should be exactly an integer-literal, not an integer inside parenthesis. The MY_INDEX_FUNCTION should be changed, so that the parameter passed to the BOOST_PP_LIST_AT is literally an integer-literal:
#define MY_INDEX_FUNCTION(x) x
The macro does not work with arithmetic expressions, this will not work:
#define MY_INDEX_FUNCTION(x) (x+1)
NOR
#define MY_INDEX_FUNCTION(x) x+1
But you can do this with
#define MY_INDEX_FUNCTION(x) MY_INDEX_FUNCTION_ ## x
#define MY_INDEX_FUNCTION_0 1
#define MY_INDEX_FUNCTION_1 2
#define MY_INDEX_FUNCTION_2 3
//...
This macro definitions can be created by a (python-)script
def my_index_function(x):
# insert the behavior of the macro here
return x+1
MACRO_NAME = "MY_INDEX_FUNCTION"
INDEX_MAX = 255
for x in range(INDEX_MAX):
print("#define %s_%i %i" % (
MACRO_NAME,
x,
my_index_function(x),
))
print("#define %s(x) %s_ ## x" % (
MACRO_NAME,
MACRO_NAME,
))
I need a little explanation over how this C++ code is behaving and returning value
#include<iostream>
using namespace std;
#define MY_MACRO(n) #n
#define SQR(x) x * x
int main()
{
//cout<<MY_MACRO(SQR(100))<<endl;
//cout<< sizeof(SQR(100))<<endl;
cout<< sizeof(MY_MACRO(SQR(100)))<<endl;
return 0;
}
As far i am concerned #n returns the number of arguments in the MY_MACRO(n) But if before that SQR(100) will be replaced by 100 * 100 (9 characters if we count spaces) But now sizeof(9) should print 4 but Its returning 9 with cout<< sizeof(MY_MACRO(SQR(100)))<<endl;
What's the catch behind it?
You are not using the right definition of #n. It is not the number of arguments. It makes it into a string.
After macro substitution your code will be converted to
sizeof("SQR(100)");
which will give 9 as size of string literal including the terminating '\0'.
#n will make the argument as string, its not the number of argument
For example :
#define display( n ) printf( "Result" #n " = %d", Result##n )
int Result99 = 78;
display( 99 ) ; // Will output -> Result99 = 78
i am using code block for learning c. my code is
#include<stdio.h>
#include<math.h>
int main()
{
int x;
x = pow(5,2);
printf("%d", x);
}
Output is 25
When i am using this code
#include<stdio.h>
#include<math.h>
int main()
{
int x,i,j;
printf("please enter first value");
scanf("%d", &i);//5
printf("please enter second value");//2
scanf("%d", &j);
x = pow(i,j);
printf("%d", x);
}
Output is 24
what is wrong here? i am just taking value using scan function and also using pow function in a same way.
I suspect you have a naive implementation of pow in your libm (I get 25, as it should be). If that computes pow(x,y) as exp(y*log(x)) for positive x without checking for (small) integral exponents and treating them specially, you get
Prelude> 2 * log 5
3.2188758248682006
Prelude> exp it
24.999999999999996
a double result slightly smaller than 25, so when that is converted to int it is truncated to 24.
To check, assign the result of pow(i,j) to a double and print that out.
With hardcoded pow(5,2), the compiler (most likely, it's what gcc does even without optimisation) computes the result during compilation exactly.
Try changing initialization to this:
int x=-1 ,i=-1 ,j=-1;
And last print to this:
printf("pow(%d, %d) == %d\n", i, j, x);
That should give good hint about the problem. Also, check return values of scanf, they should return number of items read, ie. 1 with code above.
It's almost certain, that you entered invalid input for scanf, and i or j were left uninitialized, and that 24 is just garbage value.
Also, compile with warnings enabled, and fix them (like, add return 0; to end of main).
Your code correctly gives 25 on my windows x64.
You probably needs to run it again see if you just read it wrong...
The missing "return 0;" is not the problem here.
If, anything, could ever go wrong,
you can try adding
fflush(stdin);//or out
after very scanf and printf.
If any of the flushes solves your problem, you know what is going wrong.
It seems that there is nothing wrong with the second program, except that you must add at the end
return 0;
If you read the value j with 2 then the result will be just 25.
Using your code i got result 25 which is correct.
Although Try changing the data type of result such as float or double.
I'm learning C, but I do not understand this:
#define square(x) x*x
a = square(2+3) //a = 11
When this is run, why does a end up being 11?
It expands to 2+3*2+3, which is equivalent to 2+(3*2)+3. Use parentheses to fix it:
#define square(x) ((x)*(x))
Now try it with square(x++) and you'll run into more problems (undefined behavior). Avoid doing this as a macro if you can.
square(2+3) expands to 2+3*2+3 which is equivalent to 2+(3*2)+3 [* has higher precedence than +]
On gcc you can use -E option to see what your preprocessor generates
C:\Users\SUPER USER>type a.c
#define square(x) x*x
int main()
{
a = square(2+3); //a = 11
}
C:\Users\SUPER USER>gcc -E a.c
# 1 "a.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "a.c"
int main()
{
a = 2+3*2+3;
}
Remedy
Try this
#define square(x) ((x)*(x))
Try:
#define square(x) ((x)*(x))
Because 2 + 3 is substituted literally in the expression x * x, it becomes 2 + 3 * 2 + 3, and the * operator has a higher precedence so you don't get the expected result.
Always enclose macro arguments and the whole expression in parentheses to avoid this:
#define SQUARE(x) ((x) * (x))
Also note that any expression you pass will be evaluated twice, and that can be undesired if the expression has a side effect such as an assignment, or a function call. In these cases it is better to use an inline function.
think about what you get when the macro is expanded. The c preprocessor will expand this as
a = 2 + 3 * 2 + 3
You need to correctly define your macro. Always enclose the macro variable in parenthesis. This would give you the expected result.
#define square(x) ((x)*(x))
The macro expansion would be this:
a = ((2 + 3) * (2 + 3))
Why won't this work?
0. #define CONCAT(x, y) x ## y
1.
2. #define VAR_LINE(x) \
3. int CONCAT(_anonymous, __LINE__) = x
4.
5. #define VAR_LINE2(x) \
6. int _anonymous ## x = 1
7.
8. int main()
9. {
10. VAR_LINE(1);
11. VAR_LINE(1);
12. VAR_LINE(1);
13. VAR_LINE2(__LINE__);
14. }
The result from the above macro expansion
int _anonymous__LINE__ = 1;
int _anonymous__LINE__ = 1;
int _anonymous__LINE__ = 1;
int _anonymous13 = 1;
It would be convenient if I didn't have to write that __LINE__ macro as an argument.
I'm thinking the problem is pretty clear. I want to be able to generate anonymous variables so that this macro doesn't fail with redefinition error when declaring several variables within the same scope. My idea was to use the predefined __LINE__ macro because no variable will ever be declared on the same line like this. But the macro expansion troubles me, can you help?
Update: Correct answer
Thanks to Luc Touraille. However, there was a tiny problem with the suggested solution. There has to be whitespace between the operands and the ## operator (apparently the standard says otherwise but the the PS3 flavoured GCC would not expand the macro properly if there were no whitespace between the operator and operands).
#define _CONCAT(x,y) x ## y
#define CONCAT(x,y) _CONCAT(x,y)
The VAR_LINE macro now yields:
int _anonymous10 = 1;
int _anonymous11 = 1;
int _anonymous12 = 1;
This has been verified to work under Win32 (Visual Studio 2008), XBOX360 (Xenon) and PS3.
You need to add a level of indirection so that __LINE__ will be expanded:
#define _CONCAT_(x,y) x ## y
#define CONCAT(x,y) _CONCAT_(x,y)
#define VAR_LINE(x) int CONCAT(_anonymous, __LINE__) = x