Skip to main content
gamedev.net
🔒 Locked

Template metaprogramming question

Started by felonius 13 replies 250+ views
Original Post
felonius
felonius
Hi, I have been reading game programming gems I about template metaprogramming and there is something that baffles me. The books states the following implementation of Fibonacci calculation
  
template< unsigned int N > 
struct Fib
{
  enum
  {
    Val = Fib< N-1 >::Val + Fib< N-2 >::Val
  };
};

template <> struct Fib<0> { enum { Val = 0 }; };
template <> struct Fib<1> { enum { Val = 1 }; };

#define FibT( n ) Fib< n >::Val
  
This works fine. But why does it use a struct with an embedded enum instead of just including a template function like in this implementation I wrote:
  
template< unsigned int N >
inline unsigned int Fib2(void)
{
  return Fib2< N-1 >() + Fib2< N-2 >();
}

template<> 
inline unsigned int Fib2<0>(void) 
{ 
  return 0; 
}

template<> 
inline unsigned int Fib2<1>(void)
{ 
  return 1; 
}

#define Fib2T( n ) Fib2< n >()
  
For some reason the code above doesn''t work (it returns 0 always). Why? And when I create debug builds it is not optimized away but in optimization builds it *is* reduced to just a single constant when it is used. To summarize my question: 1. Why does the second listing above not work? 2. Why does people use structs with embedded enums instead of just a inline function?
Jacob Marner, M.Sc.Console Programmer, Deadline Games
dalleboy
dalleboy
2. Why does people use structs with embedded enums instead of just a inline function?

A template struct with embedded enum can be optimized by the compiler to a single constant value. You write Fib<5>::Val and the compiler optimizes that into 120 at compile time, the functions cannot be optimized (the same way) at compile time.
felonius
felonius
quote:
Original post by dalleboy
2. Why does people use structs with embedded enums instead of just a inline function?

A template struct with embedded enum can be optimized by the compiler to a single constant value. You write Fib<5>::Val and the compiler optimizes that into 120 at compile time, the functions cannot be optimized (the same way) at compile time.


Well, when I turned optimization on with maximum inlining in MVC++ 6 the second one was optimized too, so it was reduced to a single constant. So this doesn''t really answer the question.
Jacob Marner, M.Sc.Console Programmer, Deadline Games
dalleboy
dalleboy
Try this instead (will not work either):
template<unsigned int N>
unsigned int Fib2()
{
if (N == 1)
{
return 1;
}
else if (N == 0)
{
return 0;
}
else
{
return Fib2<N-1>() + Fib2<N-2>();
}
}
Will result in (in VC++ 6):
warning C4717: 'Fib2' : recursive on all control paths, function will cause runtime stack overflow 


[edited by - dalleboy on June 15, 2002 6:31:58 AM]
felonius
felonius
Yeah, that one fails because the recursion is not ended with a template specialization, which is required to let template evaluation terminate at compile-time.

That is not the problem in the code I presented for Fib2(). It compiles and runs just fine - except that it always return 0. I am baffled.
Jacob Marner, M.Sc.Console Programmer, Deadline Games
dalleboy
dalleboy
When I tried the template function example in the debugger and stepped into the Fib2<10>() function I got into the template specialization that was at the top of the file. Ain''t that strange?

If Fib2<0> was before Fib2<1> I got this:
Fib2<10>() => Fib2<0>() => return 0

If Fib2<1> was before Fib2<0> I got this:
Fib2<10>() => Fib2<1>() => return 1

That is why I made one template function that should do everything (I thought) but instead it resulted in a runtime stack overflow.
felonius
felonius
Yes very odd. That must be a compiler error - it would be very odd otherwise.

I guess we have just found (yet another) case where MVC++ 6 is not standard compliant. So my guess as to why the struct/enum construct is used is simply to make it work with MVC++. Does this guess seem reasonable?

I was at a seminar a few days ago where the lecturer showed a table from a recent article in Dr. Dobbs journal. The authors had made a number of tests of C++ compliance - they simply measured how many of the samples from the C++ standard that would compile correctly on popular C++ compiler. *None* of the 15 or so compilers examined was standard compliant - but most could run about 90% of the samples correctly. So before people go complaining about the non-compliance of MVC++ they should know that there are no alternatives available.
Jacob Marner, M.Sc.Console Programmer, Deadline Games
JuNC
JuNC
Looks to be a MSVC++ bug, that second version works fine under gcc (2.95.2).

felonius
felonius
quote:
Original post by JuNC
Looks to be a MSVC++ bug, that second version works fine under gcc (2.95.2).




Well, that cleared that one up.

Is there anybody here that has a MVC++.NET that would be so kind as to try it out?
Jacob Marner, M.Sc.Console Programmer, Deadline Games
felonius
felonius
quote:

Compiles and runs on VC++.NET.



Thats it. I will have to go and buy an upgrade then...

Jacob Marner, M.Sc.Console Programmer, Deadline Games
Qw3r7yU10p!
Qw3r7yU10p!
quote:
Looks to be a MSVC++ bug, that second version works fine under gcc (2.95.2).



quote:
Compiles and runs on VC++.NET.



quote:
Thats it. I will have to go and buy an upgrade then...



isn't it cheaper and easier to get gcc. you could have it downloaded and working today.

[edited by - petewood on June 15, 2002 12:18:08 PM]
felonius
felonius
quote:
Original post by petewood
isn''t it cheaper and easier to get gcc. you could have it downloaded and working today.



I actually already have it installed (via cygwin) and I used it a lot back at university. I just can''t live with that development environment - but let''s not begin that discussion here shall we.


Jacob Marner, M.Sc.Console Programmer, Deadline Games
Void
Void
This is a well known hack for broken compilers. If you search around usenet groups like comp.lang.c++.moderated or microsoft.public.vc.lang, you should see lots of this.

Whenever you are "playing" with templates with VC++ and it doesn''t work, try gcc. If it still doesn''t work, try comeau (www.comeaucomputing.com). If it still doesn''t work, it''s probably your fault.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.