# CodeWarrior bug!

• 11-09-2002
Sang-drax
CodeWarrior bug!
When I was playing around a few days ago with the contest att cpphome I discovered a strange thing in CodeWarrior.

This code actually compiles!
Code:

```template <int n1, int d1, int n2, int d2> struct add_fraction {   static const int numerator;   static const int denominator; }; int gcd(int a,int b) {     if (a==b) return a;     if (a>b) return gcd(a-b,b);     return gcd(b-a,a); } template <int n1, int d1, int n2, int d2>     const int add_fraction<n1,d1,n2,d2>::numerator = (n1*d2+n2*d1)/gcd(n1*d2+n2*d1,d1*d2)); //One ) too much template <int n1, int d1, int n2, int d2>     const int add_fraction<n1,d1,n2,d2>::denominator = (d1*d2)/gcd(n1*d2+n2*d1,d1*d2);```
There's one ) too much on the red line but the code still compiles!

Note that I found a much better solution to the contest problem later, but I am quite amazed that this code is accepted!
• 11-09-2002
Sang-drax
LOL :D :D

Replace the red line with this and it still compiles:
Code:

`const int add_fraction<n1,d1,n2,d2>::numerator = (n1*d2+n2*d1)/gcd(n1*d2+n2*d1,d1*d2)))))++)--)**)%%);`
• 11-09-2002
Cgawd
there should be a contest to make a program with as many errors in the code, and see which one takes the longest to crash, WEEEEEEE
• 11-09-2002
Zahl
Now THAT's a contest of skills :D
• 11-09-2002
Fordy
I guess the part of the compiler responsible for Template Metaprogramming isnt as choosy as the proper one...

I'm trying to get a prog to do this going.....I might even enter it, but I havent got the recursion right yet (I'm doing it a little different to you)...and I dont think I will have time now.....and my maths is pretty poor :(

Ah well...!
• 11-09-2002
Sang-drax
I've got I 93 token one... but now they inform me that no other public symbols may be defined! :( :(
The contest page didn't mention this at all!
Code:

```template <int n1, int d1, int n2, int d2>     struct add_fraction     {         static const int n = n1*d2+n2*d1,                         d = d1*d2,                         gd = add_fraction<d , n%d , 0, 1>::gd,                         numerator = n / gd,                         denominator =d / gd;     }; template <int n1>     struct add_fraction<n1,0,0,1>     {         static const int gd = n1;     };```
• 11-10-2002
Fordy
Bah...I wish I had more time on this :(

Ah well...I managed to get one version working......it compiles with DevC++ 4 (which I think uses gcc 2.95 -the compiler your code needed to be compatible with) and with Codewarrior...but again chokes on VC++6

I think if I had more time (your link was my first notice) I would be able to try more stuff......Ah well!

Have a look...I think there maybe too many "tokens" as they mention......and I am unclear on what they mean by extra symbols?? (Will an enum inside a template count?? - hmm). I think he means adding to the add_fraction struct.....maybe not....ah well...its kept me entertained this morning!!

Code:

<edit> Code removed...I should wait until the contest is over (What am I thinking:rolleyes: )</edit>
• 11-10-2002
Sang-drax
The contests at cpphome are often a bit unclear.

For example, there was a prime number contest and both the winner and the guy at the second place used lookup tables, even though it was explicitly forbidden!
The speed contests also depends very much on which compiler you're using.

Template metaprogramming is a nice intellectual challenge, but not that useful IRL.
• 11-10-2002
Fordy
Quote:

Originally posted by Sang-drax
Template metaprogramming is a nice intellectual challenge, but not that useful IRL.
Yeah...I agree......

Its a neat trick, but I'm not too sure if its as great an idea as its cracked up to be.....If you are trying to create a lookup table at compile time, then its probably less tedious to add them as a resource than to use this method.......

And I dont think compilers are as geared up for it as they would need to be if it was used more...My first crack at the code worked a treat on gcc...but died on Codewarrior.....then when I tried to work on Codewarrior, if my code was bad it would kill my compiler and cause a crash.....It even locked my XP computer on 2 occassions!...and of course your original post showed some weird bugs too...:)
• 11-10-2002
Ryan
Well, as the person running the contest, I'm glad you appreciate the challenge. Again, sorry about the issues with this contest -- it's the first metaprogramming contest I've run. The next one will be as smooth as... well, smooth. :)

"Template metaprogramming is a nice intellectual challenge, but not that useful IRL."

Not exactly. THe contest doesn't properly demonstrate its usefulness, nor was it meant to. Template metaprogramming is the technique behind some of the coolest C++ libraries available. Check out Boost or Loki, for example -- they may change the way you code.

Ryan
• 11-10-2002
Fordy
Its a neat little challenge! Keep it up!

BTW, hope you got my entry.......though looking on the related forum thread on how many tokens people have go this down to, my program is probably much bigger than the others...ah well!.....:rolleyes:
• 11-10-2002
Sang-drax
Yeah, the Boost library has many useful features.
I didn't mean that templates isn't useful, they are in fact extremely useful.

But to use templates for calculations has two disadvantages. First, the values must be know at compile-time, and the sourcecode quickly becomes extremly unmaintainable.

Hmm, in fact I think we agree.
• 11-11-2002
Fordy
Typical.

The entry I submitted used a seperate template to simplify the fraction because I couldnt do it with just the struct presented in the original question........and as you cant define any new public variables I was stumped

Sitting on the train this morning, I figured out how to get rid of that spare template and hold it only with numerator & denominator defined...so I'm sitting here in work wishing I noticed this earlier.....Still, probably not the best method (a lot longer than some people @ cpphome have claimed to do it in) and I know I have too many brackets (I could dump a few, but its too late to worry now).....but I was trying to do this for ages and now its too late as the contest has finished. Ah well!

If anyones interested, this is as far as I have got so far

Code:

```#include <iostream> #include <cassert> //Main struct interface template <int n1, int d1, int n2, int d2> struct add_fraction {   static const int numerator;   static const int denominator; }; //Specialisation 1: Subvert functionality template <int n1, int d1> struct add_fraction<n1,d1,0,0> {   static const int denominator = add_fraction<d1,n1%d1,0,0>::denominator; }; //Specialisation 2: Assign value template <int n1> struct add_fraction<n1,0,0,0> {   static const int denominator = n1; }; //The Numerator template <int n1, int d1, int n2, int d2>         const int add_fraction<n1,d1,n2,d2>::numerator =         ((((d2*d1)/d1)*n1)+(((d2*d1)/d2)*n2)) /     add_fraction<((((d2*d1)/d1)*n1)+(((d2*d1)/d2)*n2)),     ((d2*d1)%((((d2*d1)/d1)*n1)+(((d2*d1)/d2)*n2))),0,0>::denominator; //The Denominator template <int n1, int d1, int n2, int d2>     const int add_fraction<n1,d1,n2,d2>::denominator = (d1*d2)/     add_fraction<((((d2*d1)/d1)*n1)+(((d2*d1)/d2)*n2)),     ((d2*d1)%((((d2*d1)/d1)*n1)+(((d2*d1)/d2)*n2))),0,0>::denominator; int main() {         typedef add_fraction<2,3,1,12> three_fourths;         assert(three_fourths::numerator==3);     assert(three_fourths::denominator==4);             int n = three_fourths::numerator;         int d = three_fourths::denominator;         std::cout << n;     std::cout << std::endl;     std::cout << d; }```