How does the preprocessor work in C? - c

Why is the answer for the below code 16? Can anybody explain the working of this program?
#define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
If we write the same code like below, then the answer is 4:
//the ans is 4 why?
#include<stdio.h>
#include<conio.h>
#define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}

The preprocessor just replaces the text, exactly as written.
So, the macro call SQUARE(2) becomes literally 2*2.
In your case, that means the whole expression becomes 16/2*2, which because of C's precedence rules evaluates to (16/2)*2, i.e. 16.
Macros should always be enclosed in parenthesis, and have each argument enclosed as well.
If we do that, we get:
#define SQUARE(n) ((n) * (n))
which replaces to 16/((2) * (2)), which evaluates as 16/4, i.e. 4.
The parens around each argument makes things like SQUARE(1+1) work as expected, without them a call such as 16/SQUARE(1+1) would become 16/(1+1*1+1) which is 16/3, i.e. not at all what you'd want.

Order of operations. Your expression is evaluating to:
j = 16 / 2 * 2
which equals 16. Make it:
#define SQUARE(n) (n*n)
which will force the square to be evaluated first.

You need to define your macro with insulating parentheses, like so:
#define SQUARE(n) ((n)*(n))
Otherwise
j = 16/SQUARE(2);
expands to
j = 16 / 2 * 2; which is equivalent to (16 / 2) * 2
When what you want is
j = 16 / (2 * 2);

1. When using macros that are to be used as expressions, you should parenthesise the whole macro body.
This prevents erroneous expansions like:
#define SQUARE(x) x*x
-SQUARE(5,5)
// becomes -5 * 5
2. If the macro arguments are expreessions, you should parenthesise them too.
This prevents a different type of problems:
#define SQUARE(x) x*x
SQUARE(5+2)
// becomes 5 + 2*5 + 2
Hence the correct way is to write it like this:
#define square(n) ((n)*(n))
-SQUARE(5+2)
// becomes -((5+2)*(5+2))
Using macros as functions is discouraged though (guess why), so use a function instead. For instance:
inline double square(n) { return n*n; }

The Expansion of macro will be like:
j = 16/SQUARE(2);
j = 16/2*2;
Which is equal to : j = (16/2)*2; Means j = 16;
and :
j = 16/(SQUARE(2));
j = 16/(2*2);
Which is equal to : j = 16/4; Means j = 4;

Because the macro will be expanded as:
j = 16/2*2;
The pre-compiler does not do any processing on the expansion. It places the expanded macro in your code as it is. Since you have not parenthesized the replacement text it wont do it for you in the main code as well. Make it :
#define SQUARE(n) ((n)*(n))

The first example is evaluated as:
16 / 2 * 2
(16 / 2) * 2
8 * 2
16
The second example is evaluated as:
16 / (2 * 2)
16 / 4
4
Add parenthesis to you preprocessor statement to control the order of operations:
#define SQUARE(n) ((n)*(n))
The outer parenthesis in ((n)*(n)) ensure that n is squared before any outside operation is performed. The inner parenthesis (n) ensure that n is correctly evaluated in cases where you pass an expression to SQUARE like so:
16 / SQUARE(2 * 2)
16 / ((2 * 2)*(2 * 2))
16 / (4 * 4)
16 / 16
1

you'll get
j =16/2*2; // (16 / 2) * 2 = 16

Its because Whenever macro name is used, it is replaced by the contents of the macro.its simple rule of working of macro.
Case 1 : result 16
define SQUARE(n) n*n
void main()
{
int j;
j =16/SQUARE(2);
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/SQUARE(2);
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/2*2
j = (16/2)*2
j = 8*2
j =16
Case 2 : result 4
define SQUARE(n) n*n
void main()
{
int j;
j =16/(SQUARE(2));
printf("\n j=%d",j);
getch();
}
its get expand as below
j =16/(SQUARE(2));
so in place of SQUARE(2) it will replace 2*2 because Macro is SQUARE(n) n*n
j = 16/(2*2)
j = 16/(4)
j = 4
Hope this will help

Related

Whats the logic behind the output [duplicate]

I was just going through certain code which are frequently asked in interviews. I came up with certain questions, if anyone can help me regarding this?
I am totally confused on this now,
#include <stdio.h>
#include <conio.h>
#define square(x) x*x
main()
{
int i, j;
i = 4/square(4);
j = 64/square(4);
printf("\n %d", i);
printf("\n %d", j);
printf("\n %d", square(4));
getch();
}
The output is:
4
64
16
I am wondering, why did square(4) return 1 when I divided it? I mean, how can I get the value 4 and 64 when I divide it, but when used directly I get 16!!?
square is under-parenthesized: it expands textually, so
#define square(x) x*x
...
i=4/square(4);
means
i=4/4*4;
which groups as (4/4) * 4. To fix, add parentheses:
#define square(x) ((x)*(x))
Still a very iffy #define as it evaluates x twice, so square(somefun()) calls the function twice and does not therefore necessarily compute a square but rather the product of the two successive calls, of course;-).
When you write i=4/square(4), the preprocessor expands that to i = 4 / 4 * 4.
Because C groups operations from left to right, the compiler interprets that as i = (4 / 4) * 4, which is equivalent to 1 * 4.
You need to add parentheses, like this:
#define square(x) ((x)*(x))
This way, i=4/square(4) turns into i = 4 / ((4) * (4)).
You need the additional parentheses around x in case you write square(1 + 1), which would otherwise turn into 1 + 1 * 1 + 1, which is evaluated as 1 + (1 * 1) + 1, or 3.
i=4/square(4);
expands to
i=4/4*4;
which equivalent to
i=(4/4)*4;
Operator precedence is hurting you.
The macro is expanded by the pre-processor such that
i=4/4*4;
j=64/4*4;
which is equivalent to:
i=(4/4)*4;
j=(64/4)*4;
That's because the compiler replaces it with:
i=4/4*4;
j=64/4*4;
i = (4/4)*4 = 1*4 = 4.
j = (64/4)*4 = 16*4 = 64.
j = 4/square(4) == 4/4*4 == 1*4 == 4
Manually expand the macro in the code, and it will be clear. That is, replace all the square(x) with exactly x*x, in particular don't add any parentheses.
define is just a text macro
main()
{
int i,j;
i=4/ 4 * 4; // 1 * 4
j=64/4 * 4; // 16 * 4
printf("\n %d",i);
printf("\n %d",j);
printf("\n %d",square(4));
getch();
}
It's a macro! So it returns exactly what it substitutes.
i = 4/4*4; Which is 4...
j = 64/4*4; Which is 16...
Try this for your macro:
#define square(x) ((x)*(x))
Because of operator precedence in the expression after the preprocessor - you'll need to write
#define square(x) (x*x)
As the other answers say, you're getting burned by operator precedence. Change your square macro to this:
#define square(x) (x*x)
and it'll work the way you expect.

There is a sentence about "statement" that I can't understand in C Primer Plus by Stephen Prata [duplicate]

This question already has answers here:
Expression Versus Statement
(21 answers)
Closed 6 years ago.
There is a sentence about "statement" that I can't understand in C Primer Plus by Stephen Prata.
In Chapter 5, there is a section which explains difference between statement and expression. The author explains statement as follows:
Statements
Statements are the primary building blocks of a program. A program is a series of statements with some necessary punctuation. A statement is
a complete instruction to the computer. In C, statements are indicated
by a semicolon at the end. Therefore,
legs = 4
is just an expression (which could be part of a larger expression), but legs = 4;
is a statement.
And then the author gives an example:
Although a statement (or, at least, a sensible statement) is a complete instruction, not all complete instructions are statements.
Consider the following statement:
x = 6 + (y = 5);
In it, the subexpression y = 5 is a complete instruction, but it is only part of the statement. Because a complete instruction is not
necessarily a statement, a semicolon is needed to identify
instructions that truly are statements.
The authors says that "y=5"is a complete instruction but as she mentioned above isn't this just an expression, not a complete statement?
Every C program comprises of Statements. Program executes statement by statement. Each statement generally, in turn, comprises of some expression. And an expression may further comprise of sub-expressions. For example:
/* diff_statements.c */
#include <stdio.h>
#define SIZE 10 /* SIZE symbolic constant */
int main(void)
{
int index, sum; /* declaration statement */
int boys[SIZE]; /* array declaration */
printf("user enter no of boys in 10 classes...\n");
/* function statement */
for (index = 0; index < SIZE; index++)
scanf("%d", &boys[index]);
/* for statement with single statement */
/* IT'S A GOOD PRACTICE TO REVIEW IF U ENTERED CORRECT VALUES */
printf("No. of boys you entered for 10 classes are as:\n");
for (index = 0; index < SIZE; index++)
printf("%d\t", boys[index]);
printf("\n");
printf("Summing up & Displaying boys in all classes...\n");
/* for statement with block of statements */
for (index = 0; index < SIZE; index++) {
sum += boys[index];
; /* Null Statement; this does nothing here */
}
printf("Total boys in %d classes is %d\n", SIZE, sum);
return 0;
}
Every C statement ends with a semicolon ‘;’. While expressions don’t. For example:
x + y; /* x + y is an exp but x + y; is a statement. */
5 + 7; /* similarly as above */
while (5 < 10) {
/* 5 < 10 is a relational exp, not a statement. */
/* used as a while test condition */
/* other statements in while loop */
}
result = (float) (x * y) / (u + v);
okey = (x * y) / (u + w) * (z = a + b + c + d);
/* (z = a + b + c + d) is a sub-expression in the above */
/* expression. */
Expressions are complete instruction in human logic, but not according to C. From point of view of C, a complete instruction is a Statement, that is a valid combination of expressions ended with a semi-colon.

Macro function to behave like for loop

Consider the following code i managed to write:
#include <stdio.h>
#define FOR(A, B, C) for(A; B; C++)
int main()
{
FOR(i=0, i<10, i)
printf("%i", i);
return 1;
}
The output is:
0123456789
If i do FOR(i=5, i<10, i)
then respectively the output is 56789
My questions are is that legal? Will it cause any errors in different cases? Does it works exactly like a for loop?
Yes it's a "legal" macro, but no, it does not work like a real for loop.
Your macro won't handle this:
int a, b;
for(a = 0, b = 4711; a < b; ++a);
for instance, since you can't distinguish the , used to build a longer initializing expression to the one used to separate the expressions that make up the parts:
FOR(a = 0, b = 0, a < b, ++a);
will break, since it looks like a call with 4 arguments instead of 3.
A macro is just copied everywhere the preprocessor sees you using the macro keyword. It just copies the text, nothing more.
To elaborate on that a bit more, consider this example:
#define MY_MACRO a
int MY_MACRO = 5;
When the preprocessor comes along it will take the above and change it to:
int a = 5;
and then the compiler will come along and compile it like normal C/C++ code.
When you add arguments to your macro, they are just substituted in place within your macro. This can be a problem, consider the following two macros:
#define BAD_MACRO(a, b) a*b
#define GOOD_MACRO(a, b) (a)*(b)
They look almost the same, but consider the following:
int k = BAD_MACRO(2, 3); // k = 2*3 = 6
int j = GOOD_MACRO(2, 3); // j = 2*3 = 6
int m = BAD_MACRO(2+1, 3); // m = 2+1*3 = 5
int n = GOOD_MACRO(2+1, 3); // n = (2+1)*3 = 9
Although note that neither of these macros are good or bad, they just don't have the same behaviour as a typical function.

Unexpected output in c [duplicate]

This question already has answers here:
C macros and use of arguments in parentheses
(2 answers)
Closed 4 years ago.
I am new to c language. I just wanted to know why is my macro not working properly. It is giving me output as 13 where as my expected output is 24.?
#include<stdio.h>
#define mult(a,b) a*b
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
mult(x+2,y-1) expands to x +2 * y -1 that is equals to 4 + 2 * 5 -1 gives output: 13.
You might be expecting answer (4 + 2) * (5 -1) = 6 * 4 = 24. To make it expand like this you should write parenthesize macro as #H2Co3 also suggesting:
#define mult(a,b) ((a)*(b))
Read aslo: So, what's wrong with using macros? by Bjarne Stroustrup.
This is because C macros are simple textual substitutions, the macro writer must be sure to insert parentheses around every macro variable when it is substituted, and around the macro expansion itself, to prevent the resulting expansion from taking on new meanings.
If you observe your program: mult(a, b) is defined as a * b
mult(x + 2, y - 1) = x + 2 * y - 1 = 4 + 2 * 5 - 1 = 4 + 10 - 1 = 13
The Correct way would be:
mult(a, b) ((a) * (b))
Use parentheses in the macro definition
#include<stdio.h>
#define mult(a,b) ((a)*(b))
int main()
{
int x=4,y=5;
printf("%d",mult(x+2,y-1));
return 0;
}
This is because different arithmetic operators have different precedence levels. Hence always use parentheses while defining the macro.
Because it replaces the arguments literally:
mult(x+2,y-1) --> mult(4+2,5-1) --> 4 + 2*5 - 1 --> 13
Try changing the define to:
#define mult(a,b) (a)*(b)
In this case the result after pre-processing is this:
int main()
{
int x=4,y=5;
printf("%d",(x+2)*(y-1));
return 0;
}
This will solve the problem but it's still not the best way to do it.
#define mult(a,b) ((a)*(b))
This version is considered as good practice because in other types of situation the first one would fail. See the bellow example:
#include<stdio.h>
#define add(a,b) (a)+(b)
int main()
{
int x=4,y=5;
printf("%d",add(x+2,y-1)*add(x+2,y-1));
return 0;
}
In this case it would give an incorrect answer because it is translated by the pre-processor to the fallowing:
int main()
{
int x=4,y=5;
printf("%d",(x+2)+(y-1)*(x+2)+(y-1));
return 0;
}
printing 34 instead of 100.
For the ((a)+(b)) version it would translate to:
int main()
{
int x=4,y=5;
printf("%d",((x+2)+(y-1))*((x+2)+(y-1)));
return 0;
}
giving a correct answer.

Call by Name with dynamic scoping

I am stuck at the following problem on static/dynamic scoping:
The following program fragment is written in a programming language that allows global
variables and does not allow nested declarations of functions.
global int i = 100, j = 5;
void P(x) {
int i = 10;
print(x + 10);
i = 200;
j = 20;
print (x);
}
main() {P(i + j);}
Q1. If the programming language uses static scoping and call by need
parameter passing mechanism, the values printed by the above program
are
(A) 115, 220 (B) 25, 220 (C) 25, 15 (D) 115, 105
Q2. If the programming language uses dynamic scoping and call by name
parameter passing mechanism, the values printed by the above program
are
(A) 115, 220 (B) 25, 220 (C) 25, 15 (D) 115, 105
What I think:
On Q1: As it's static scoping and as per call by need, x should be replaced with i + j. But it will cause a local name conflict as there is already a variable with name i. So it (the global i) might be renamed, lets say to i1, and then call will be:
first call: print(x+10) -> (i1 + j + 10) -> (100 + 5 + 10) -> 115
second call: print(x) -> print(i1 + j) -> 105 (Already evaluated - call by need)
On Q2: In dynamic scoping, you search for a variable in the local function first, then you search in the function that called the local function, then you search in the function that called that function, and so on, up the call stack.
As per call by name:
print (i1 + j + 10) -> print (100 + 5 +10 ) -> 115
And the second call will be
print(x) -> print(i1 + j) -> (100 + 20) = 120 // Evaluate again - Call be name.
Is this answer correct? (Not present in the options)
Is there something I'm missing? (Dynamic binding may be?)
Q1
OP's answer is correct (D). In fact, because global i is not modified during the execution of P, there is no difference between call by need and call by value.
Here is an example where it does make a difference:
global int i = 100, j = 5;
void IncreaseTheGlobal() {
i = i + 1; // static scoping means this is the GLOBAL i!
print(i);
}
void P(x) {
int i = 10;
IncreaseTheGlobal(); // 101 (increased global i)
print(i); // 10 (local i)
print(x); // 106 (x is evaluated; picks up increased global i)
IncreaseTheGlobal(); // 102 (2nd time increased global i)
print(x); // 106 (x not re-evaluated; unaffected by 2nd increase)
}
main() {
print(i); // 100 (original global i)
P(i + j);
print(i); // 102 (new global i)
}
As already pointed out by OP, the first time x is evaluated, it picks up whatever value global i has at that particular moment. After that initial evaluation, x is no longer affected by a later modification of global i.
Q2
Call by name is typically used in macro languages. So why not use the best known macro language ever: the C preprocessor?
#include <stdio.h>
int i = 100, j = 5;
#define print(num) printf("%d\n", num)
#define P(x) { \
int i = 10; \
print(x + 10); \
i = 200; \
j = 20; \
print(x); \
}
main() {
P(i + j);
}
Compile, run, and see: 25, 220.
Call by name works with a simple search-and-replace; within the body of P, replace every occurrence of x by i + j.
int i = 10;
print(i + j + 10); // 10 + 5 + 10 = 25
i = 200;
j = 20;
print(i + j); // 200 + 20 = 220
In other words, the i and the j inside i + j just pick up the present value of whatever happens to be in scope when x is evaluated.
So the correct answer is B, right? Well, almost... the correct answer depends on the implementation of print.
Suppose print practices call by name too, and print defines its own local variable i, then that would dramatically change the result. Try this:
#define print(num) { int i = 0; printf("%d\n", num); }
The result now changes to 15, 20.
This is probably the most important reason why dynamic scoping is bad for the maintainability of your code. Implementation changes in function print (even something trivial as changing the name of a local variable) might break functions on a higher level.
In the second part that is Call by name
The line i=200 will update the local i
Now while print(x) is called it will be replaced by print(i+j)=>print(200+20)=>220
For Q1:
int i = 10;
print(x + 10); // print (i + j + 10); prints 10 + 5 + 10 = 25; local i gets used here
i = 200;
j = 20;
print (x); // print (i + j); call by need ensures, no reevaluation and i + j is 15.
So, answer is C - 25, 15

Resources