954,496 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Confused

#include <stdio.h>
#define a b
#define b a
int main(void)
{
 int a = 20, b = 30;
 printf("%d %d", a, b);
}


What will be the output of this programm ??????????????
Really confused with this ... Can somebody tell me what exactly will be happen and how macros will be replaced in the preprocessing stage.
This is my preprocessor output ....

int main(void)
{
 int a   = 20, b   = 30;
 printf("%d %d", a  , b  );
}

No change .... :rolleyes:

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 

You havn't done anything with your definitions, try this:

#include <stdio.h>
#define a_b

int main(void)
{
#ifdef a_b
 int a = 20, b = 30;
#endif
#ifdef b_a
  int b = 20, a = 30;
#endif
 printf("%d %d", a, b);

}
hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

Output will be 20 30, This seems to straightforward for me.

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 
#include <stdio.h>

 
#define a b
#define b a
int main(void)
{
int a = 20, b = 30;
printf("%d %d", a, b);
}


In the above code

a will be replaced by b and
b will be replaced by a.

In that case

int a = 20


will become

int a = 20


.
That I understood.
But what is confusing me is why,

int b= 30


is not getting replaed to

int a = 30


???

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 

Doh! ! I can't believe I am soooo thick!

It swaps every instance of a and b so

printf("%d %d", a, b);

becomes

printf("%d %d", b, a);
hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 
int main(void)
{
 int a   = 20, b   = 30;
 printf("%d %d", a  , b  );
}


But why there is no change in the preprocessor output ( see above) ???

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 

I'm guessing here, but I recon they cancel each other out.

All directives run on each instance, so:

Preprocessor finds the first instance of a and runs ALL directives on it
a = b = a
Then it finds the first instance of b and applied all directives to it
b = a = b

and so on...

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

Are you sure about this. I just want to confirm .... Do you know any good materials on this.

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 

I stated I was guessing and if I have any good material I would quote it.

I came to this conclusion by thinking about it and applying a process of elimination in my mind, by thinking about how a compiler program would implement a preprocessor.

Take one of your directives away and look at the output, then put that back and remove the previous directive and look at the output. Can there be any other explanation ?

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

It must vary depending on the compiler, here's a good llink for the GNU C Preprocessor. (the one I am using)

http://www.channelu.com/NeXT/NeXTStep/3.3/nd/DevTools/12_Preprocessor/Preprocessor.htmld/index.html

Read the bit about 'Cascaded Use of Macros'

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

Using one directive the output is as I am expecting.
In this case it will give redefinition error. But when I use two not able to figure out what is happening

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 
In this case it will give redefinition error

You are running preprocessor ONLY you saidBut when I use two not able to figure out what is happening

Did you read the material I posted? http://www.channelu.com/NeXT/NeXTStep/3.3/nd/DevTools/12_Preprocessor/Preprocessor.htmld/index.html

you asked for material I (posibly wasted) valuable time looking that up for you, please tell me you at least looked at it.

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

I'm guessing here, but I recon they cancel each other out.

All directives run on each instance, so: Preprocessor finds the first instance of a and runs ALL directives on it a = b = a Then it finds the first instance of b and applied all directives to it b = a = b

and so on...

I also think this is the correct interpretation.-8- A preprocessing directive of the form [INDENT] # define identifier replacement-list new-line
[/INDENT]defines an object-like macro that causes each subsequent instance of the macro name* [INDENT][Footnote: Since, by macro-replacement time, all character literals and string literals are preprocessing tokens, not sequences possibly containing identifier-like subsequences (see 2.1.1.2, translation phases), they are never scanned for macro names or parameters. --- end foonote][/INDENT]to be replaced by the replacement list of preprocessing tokens that constitute the remainder of the directive.* [INDENT][Footnote: An alternative token (lex.digraph) is not an identifier, even when its spelling consists entirely of letters and underscores. Therefore it is not possible to define a macro whose name is the same as that of an alternative token. --- end foonote][/INDENT]The replacement list is then rescanned for more macro names as specified below.

16.3.4 - Rescanning and further replacement [cpp.rescan]

-1- After all parameters in the replacement list have been substituted, the resulting preprocessing token sequence is rescanned with all subsequent preprocessing tokens of the source file for more macro names to replace.
-2- If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file's preprocessing tokens), it is not replaced. Further, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.
-3- The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one.
You can see the above more clearly by preprocessing the following program.

#define a b a
#define b a
int main(void)
{
 int a = 20, b = 30;
 printf("%d %d", a, b);
}
WolfPack
Postaholic
Moderator
2,051 posts since Jun 2005
Reputation Points: 572
Solved Threads: 115
 

At last the calvary arrives, I was starting to feel like Genral Custer!

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

I would put this under "undefined behavior" and assume defining a to be b then b to be a to be a bad practice. Therefore I would abandon the concept of understanding what the compiler would do and move on to a different problem -- one that makes sense...

Just my 2 cents.

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Thank you all for your suggestions.

hollystyles - Good material.

dilip.mathews
Junior Poster in Training
89 posts since Jun 2006
Reputation Points: 16
Solved Threads: 3
 
I would put this under "undefined behavior"

But it is clearly defined in the document to which I posted a link. It is important to understand in great depth the tools you work with. It is very possible for a large project to have potentialy conflicting pre-processor directives- not as simplistic as the example postulated here but no less poignant - like this.

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 
I would put this under "undefined behavior"
But it is clearly defined in the document to which I posted a link. It is important to understand in great depth the tools you work with. It is very possible for a large project to have potentialy conflicting pre-processor directives- not as simplistic as the example postulated here but no less poignant - like this.


But is that defined only for Dev or is it defined in the language standards? If only in Dev, then it's a bad thing to rely on. When you change compilers, according to your suggestion, you must then start the "great depth" learning curve from scratch as you try to track down why your programs no longer function correctly.

IMO, you need to understandthe language in great depth, not the tool's version of the language. Try to avoid compiler-dependant functions and implementations whenever possible. Wolfpack has the correct idea, and that is by quoting the C++ Standard

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Hmmm...

Yes you should know the language well, but without a compiler (standards compliant or not) it is useless.

The language is just the wood, it is the tool and the "in depth" knowledge of it which produces the craft. A cabinet maker chooses his tools very carefully and lives with them until they become extensions of his own limbs. Standards are important and have their job to do but IMHO you certainly shouldn't rely on them they change often, will always be open to interpretation and sometimes blatantly ignored.

hollystyles
Veteran Poster
1,182 posts since Feb 2005
Reputation Points: 262
Solved Threads: 68
 

But stilll i agree with WaltP.

IF any construct or any stmt for eg. fflush (stdin) suppose would be defined under one compiler it would make really less sense to adopt it if it results in undefined behaviour on other compilers. (though it really is undefined under all implementations)

In the end, undefined behaviour of any kind should be very much avoided.

And btw carrying on with ur eg., if the artist knows what wood he is supposed to use and the knowledge of how that wood can be made into a beautiful engraving or a piece of art then it really doesnt matter in which part of the world he is, he just needs to know wat tools are at his disposal and he is all set to make the next masterpiece.

In the end its the knowledge which is more important than the tool, so if asked to make a choice i would very muchchoose Knowledge over proficiency of a particular Tool.

Hope u take all this is good faith.
Bye.

~s.o.s~
Failure as a human
Administrator
11,938 posts since Jun 2006
Reputation Points: 3,281
Solved Threads: 734
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You