C macro with expression unwanted result - c

I am running the following program and getting a result as 9 7, I understood why 9 is the output but I can't figure out why I'm getting 7 as output.
#include<stdio.h>
#define sqr(i) (i*i)
int main()
{
printf("%d %d", sqr(3), sqr(3+1));
return 0;
}
For the second function that is sqrt(3+1) how the micro is getting expanded and how Im getting 7 output?

You can have the compiler or IDE preprocess the file and show you how the macro expanded.
In your case sqr(3+1) expands to (3+1*3+1). Now the precedence of C operators means that the multiplication is done before the addition. So (3+1*3+1) -> (3+3+1) -> (7).
You can fix this by defining your macro this way, with parentheses around the argument:
#define sqr(i) ((i)*(i))

Related

Missing parenthesis when using macros in C?

I am getting a 'bad suffix on number' and a missing parenthesis at the last printf.
Do you have any idea why this is not working?
#include <stdio.h>
#define suma(a, b) a + b
#define alipire(a,b) a##b
int main()
{
int a = 2, b = 3, maxim;
maxim = a > b ? a : b;
printf("%d \n",suma(a, b)*5);
printf("%d", alipire(suma(a, b), maxim));
return 0;
}
When the macro suma(a, b) is replaced in printf("%d \n",suma(a, b)*5);, the result is printf("%d \n",a + b *5);, which may not be what you want as it multiplies b by 5 before adding a.
When alipire(suma(a, b), maxim) is replaced, the steps are:
alipire is initially replaced by suma ( a , b ) ## maximum. I inserted spaces to emphasize the organization into preprocessor tokens.
The ## is processed to concatenate tokens. This would form suma ( a, b )maximum. However, )maximum is not a valid preprocessor token. Per the rule in C 2018 6.10.3.3 3, the behavior is not defined.
Attempting to reproduce the problem with various major compilers, include MSVC, on Compiler Explorer yielded various error messages but not “bad suffix on number”. Perhaps you are using an older version of Visual Studio or the source code that produced that error was different from the source code shown in the question. So specific analysis for that error message cannot be done without more information, such as the specific compiler version and command-line switches used.

How ## operator in macro works?

I was studying some macro operations, and I got this Code and I was unable to figure out how this code is actually working and generates the output? and is there any (i-+) operator that exists or not?
Here is the code
#include<stdio.h>
#define p(a,b) a##b
#define call(x) #x
int main()
{
do{ int i=14,j=3;
printf("%d",p(i-+,+j));
}while(*(call(625)+3));
return 0;
}
Output is 10.
It will be very helpful if you explain it with some examples.
The ## in the macro is the concatenation operator, it glues its operands together. So after the preprocessor is done, that expression will be
i-++j
which of course just means i - (++j), i.e. 14 - 4 which of course is 10.

Why doesn’t the preprocessor cause two adjacent minus signs to be a decrement? [duplicate]

This question already has answers here:
strange result on macro expansion
(4 answers)
Closed 5 years ago.
Consider the following code:
#include <stdio.h>
#define A -B
#define B -C
#define C 5
int main()
{
printf("The value of A is %d\n", A);
return 0;
}
Here preprocessing should take place in the following manner:
first A should get replaced with -B
then B should get replaced with -C thus expression resulting into --C
then C should get replaced with 5 thus expression resulting into --5
So the resultant expression should give a compilation error( lvalue error ).
But the correct answer is 5, how can the output be 5?
Please help me in this.
It preprocesses to (note the space):
int main()
{
printf("The value of A is %d\n", - -5);
return 0;
}
The preprocessor pastes tokens, not strings. It won't create -- out of two adjacent - tokens unless you force token concatenation with ##:
#define CAT_(A,B) A##B
#define CAT(A,B) CAT_(A,B)
#define A CAT(-,B)
#define B -C
#define C 5
int main()
{
printf("The value of A is %d\n", A); /* A is --5 here—no space */
return 0;
}
Although the C preprocessor often feels like it’s literally doing a search and replace on the code, the preprocessor actually works a bit differently.
Before the preprocessor runs, the source file is split into preprocessing tokens, which are individual units of text. For example, a single minus sign is treated not as a character, but as a token consisting of a minus sign, and a double minus sign is treated as a token consisting of two minus sign.
The C preprocessor kicks in and replaces each macro not with the literal text of the macro replacement, but rather with the series of preprocessor tokens in that replacement. In this case, the preprocessor replaces A with a minus followed by B, then replaces B with a minus followed by C, then replaces C with 5. The effect here is that there are two unary minuses applied to the 5, rather than a decrement operator, even though a literal search and replace would have generated a decrement operator that produces a syntax error.
This is interesting in that there’s no way you can write two consecutive minus signs in source code and have it interpreted as two unary minuses. This only works because by the time the preprocessor splices everything together, it already knows it’s looking at two unary minuses. The resulting C code isn’t then rescanned to be tokenized a second time around.
Now the legalese: section §5.1.1.2/7 says that after macro substitution is done, each preprocessing token - and here there are two of them (the two minus signs) - are converted into actual tokens, and then they’re syntactically and semantically analyzed. That means that there’s no opportunity for the compiler to rescan those tokens to reinterpret them as a single token. So this is a weird case where the resulting token stream can’t actually be typed into the source code without changing the meaning.
Think of the resultant expression as this instead:
-(-(5))

#define directive in C Giving ambiguous answer [duplicate]

This question already has answers here:
C : #define usage [duplicate]
(3 answers)
Closed 7 years ago.
#include <stdio.h>
#define SQR(x) x*x
int main()
{
printf("%d",225/SQR(15));
return 0;
}
The output to this code is 225. I'm unable to understand as what really is happening here.
If I use #define SQR(x) (x*x) Then it works fine which i get as we are supposed to use parentheses if we have an expression with some operator.
But in the previous case I'm not clear as to what is really happening. Why is the answer 225?
#define macros aren't functions - they are just macros, text replacement. If you take the expression 225/SQR(15) and replace SQR with 15*15, you'll get 225/15*15, and since / and * have the save precedence and are left associative - 255/15*15 = 255.
Macros do substitution only(done before compilation of the code).
Therefore the following line
printf("%d",225/SQR(15));
after substitution will become:
printf("%d",225/15*15);
now this expression evaluates to 225 (basic maths : divide first -> 15*15, then multiply -> 225)
using brackets solves your problem(then it becomes 225/(15*15)).
:)
Notice the steps
1) 225/SQR(15)
2) 225/15*15
Division executed first due to precedence
3) 15*15
4) 225
See #define as a text replacement tool in a text editor; it works the same way (well, almost).
Here are two rules you might want to follow in order to avoid this kind of errors:
When working with macros, always use parentheses for each "variable" given to the macro and for the whole result.
Example:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
When you have an unexpected behavior, use the command line tool cpp (c preprocessor) to see how the macro is actually interpreted.
Example:
$ cpp main.c

Why does my C program output this?

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.

Resources