code confusion???
code confusion???
# 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]
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......
found a solution at ::: http://www.mega-tokyo.com/forum/index.p ... adid=10453
imagination is once limit......
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
Macros not defined according to known flaws are evil.Colonel Kernel wrote:This is why macros 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.
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 callColonel Kernel wrote:This is why macros are EVIL.
#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.
- Colonel Kernel
- Member
- Posts: 1437
- Joined: Tue Oct 17, 2006 6:06 pm
- Location: Vancouver, BC, Canada
- Contact:
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.Ready4Dis wrote:Bad programming is EVIL, that's why you should always use { and } after an if statement, then these problems don't happen.
Top three reasons why my OS project died:
- Too much overtime at work
- Got married
- My brain got stuck in an infinite loop while trying to design the memory manager
Hi.
That's "interesting" ...
How about this:
and
This case is easier to avoid than that one.
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).
That's "interesting" ...
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?
...
Code: Select all
int inc(x){
return x++;
}
...
int a=2,b;
b=inc(a)*inc(a); //And now?
...
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).
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.
#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.
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.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!
Every good solution is obvious once you've found it.