code confusion???

Programming, for all ages and all languages.
Post Reply
rich_m
Member
Member
Posts: 33
Joined: Sat Nov 25, 2006 10:05 am

code confusion???

Post by rich_m »

# define swap(a,b) temp=a; a=b; b=temp;

main( )
{
int i, j, temp;
i=5;
j=10;
temp=0;
if( i > j)
swap( i, j );
printf( "%d %d %d", i, j, temp);
}
[/code]
imagination is once limit......
rich_m
Member
Member
Posts: 33
Joined: Sat Nov 25, 2006 10:05 am

Post by rich_m »

imagination is once limit......
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Erm... where is the problem?

Output is "5 10 0", becaue i > j is false and swap() never gets called...
Every good solution is obvious once you've found it.
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

I disagree :twisted:

Output is 10 0 0, because when the macro expands, the only line affected by the if statement will be temp=a.

a=b and b=temp will still execute.

Adam
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

:shock:

*slapshisforehead* *doesitagainjustHARDER*

You got me. I admit defeat. :lol:
Every good solution is obvious once you've found it.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

This is why macros are EVIL. :twisted:
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Colonel Kernel wrote:This is why macros are EVIL. :twisted:
Macros not defined according to known flaws are evil.

The macro concept isn't a proper abstraction for not automatically hiding these kinds of things.

Macros created within the known fixes for flaws are not evil but useful. That's why they're still important to learn and widely used.

I'm hoping C++0x will be mainstream pretty soon since it includes a technique that allows more template metaprogramming that makes most macro metaprogramming superfluous, hopefully obsoleting it.
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Colonel Kernel wrote:This is why macros are EVIL. :twisted:
Bad programming is EVIL, that's why you should always use { and } after an if statement, then these problems don't happen. I love macro's, they make life easy :). You don't even want to see some of my source code for my virtual machine, lol, the entire thing is almost made of macro's. Very confusing to anybody trying to write software for it, but makes it very easy to add opcodes ;). For things to do with math, I just call

#define ADD +=
#define SUB -=
#define INC ++
#define DEC --

#define MATH(r1,r2,func)\
r1 func r2;\
SetFlags(r1);

#define OpCode(OpType,Func,Reg1,Reg2,Index)\
case Index:\
OpType(Reg1,Reg2,Func)\
break;


switch (Program[PC])
{
OpCode(MATH,ADD,REGINT1,REGINT2,0x01);
OpCode(MATH,SUB,REGINT1,REGINT2,0x02);
OpCode(MATH,INC,REGINT1,,0x03);
OpCode(MATH,DEC,REGINT1,,0x04);
};

This is pretty much how the entire things runs ;). Everything is inline, it's very simple to expand for me, and it is entirely macro driven.
User avatar
Colonel Kernel
Member
Member
Posts: 1437
Joined: Tue Oct 17, 2006 6:06 pm
Location: Vancouver, BC, Canada
Contact:

Post by Colonel Kernel »

Ready4Dis wrote:Bad programming is EVIL, that's why you should always use { and } after an if statement, then these problems don't happen.
I wouldn't call Solar's simple oversight a case of bad programming. It's a mistake that's all too easy to make. IMO we should design languages to make it harder to express mistakes, not easier. I would start by making the { and } mandatory for every control statement. :)
Top three reasons why my OS project died:
  1. Too much overtime at work
  2. Got married
  3. My brain got stuck in an infinite loop while trying to design the memory manager
Don't let this happen to you!
m
Member
Member
Posts: 67
Joined: Sat Nov 25, 2006 6:33 am
Location: PRC

Post by m »

Hi.
That's "interesting" :roll: ...
How about this:

Code: Select all

#define inc(x) x++
...
int a=2,b;
b=inc(a)*inc(a);    //What's the value of b?
...
and

Code: Select all

int inc(x){
    return x++;
}
...
int a=2,b;
b=inc(a)*inc(a);    //And now?
...
This case is easier to avoid than that one. :P
As you've said,it's caused by bad programming.When using a macro or other things for pre-processor it's may be necessary two check twice:
-if the macro has a side effect for its next call(esspecially when it's not explicit);
-if a single-line macro(#define) has a inner structure with a syntax indication or which is not complete one.
Whether the pre-processor is good depends on how you use it(I think). :)
Ready4Dis
Member
Member
Posts: 571
Joined: Sat Nov 18, 2006 9:11 am

Post by Ready4Dis »

Again, that example is bad programming. If my statement uses something like ++, or anything that can be passed to it with a math statement, I always put ( ) around it just incase. Also,

#define inc(x) (++x)

This is what you're looking for ;). The pre increment, rather than post increment. All else fails, cut/paste your macro into the code where it's broken, and it gives you a nicer view of what's going on! Macro's are very useful, but you do have to be careful and understand exactly how they are working. Also, the original problem could be fixed by doing this:

# define swap(a,b) {temp=a; a=b; b=temp;}

Then you need not worry if the for loop has { } or not. Just a little pre planning and you don't run into the problems.

btw, i didn't mean his programming in general was bad, just the way he did a few things, like not putting the { } in his for loop or putting containers around his macro just for cases like this.
User avatar
Solar
Member
Member
Posts: 7615
Joined: Thu Nov 16, 2006 12:01 pm
Location: Germany
Contact:

Post by Solar »

Ready4Dis wrote:All else fails, cut/paste your macro into the code where it's broken, and it gives you a nicer view of what's going on!
You could also use gcc -E to get the output of the preprocessor. Some of the more "esoteric" constructs (#, ##...) might not be trivial to resolve by copy&paste.
Every good solution is obvious once you've found it.
m
Member
Member
Posts: 67
Joined: Sat Nov 25, 2006 6:33 am
Location: PRC

Post by m »

Ready4Dis wrote: #define inc(x) (++x)
This is what you're looking for :wink: .
Aha! :P
Sorry for posting that in a hurry and thanks for pointing that out.
Post Reply