<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	>
<channel>
	<title>Comments on: Recursion Depth Counting</title>
	<atom:link href="http://blog.froglogic.com/2007/04/recursion-depth-counting/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/</link>
	<description>A company weblog</description>
	<pubDate>Mon, 08 Sep 2008 01:46:48 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5</generator>
		<item>
		<title>By: PAF</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-203</link>
		<dc:creator>PAF</dc:creator>
		<pubDate>Wed, 18 Apr 2007 00:08:17 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-203</guid>
		<description>better late than never: what about making your template argument a void*, and use the function itself as the template argument. You would get a separate object for each function, clashing only if the two functions are ... the same.
Maybe this would work with a char* template argument and then using some predefined macro to make a unique string for each function, like __FILE__ #__LINE__

In these cases, thread-safety would have to be implemented in the RecursionCounter itself.</description>
		<content:encoded><![CDATA[<p>better late than never: what about making your template argument a void*, and use the function itself as the template argument. You would get a separate object for each function, clashing only if the two functions are &#8230; the same.<br />
Maybe this would work with a char* template argument and then using some predefined macro to make a unique string for each function, like __FILE__ #__LINE__</p>
<p>In these cases, thread-safety would have to be implemented in the RecursionCounter itself.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Knic Knic</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-185</link>
		<dc:creator>Knic Knic</dc:creator>
		<pubDate>Sat, 14 Apr 2007 19:31:18 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-185</guid>
		<description>Personally I always use a different solution (of course it adds to stack bloat, but whatever) but it has served me well in programming competitions. Also the compiler wont catch it if you make a call to f without using the parameter recursionDepth, which can lead to annoying bugs. However default parameters never bit in this case, because I pretty much always have a depth in there.

void f(int recursionDepth = 0)
{
    ++recursionDepth;    

    printf( "Recursion depth is: %dn", recursionDepth );
    // Lots of code here; for each return path, don't forget
    // to decrement recursionDepth!    


}</description>
		<content:encoded><![CDATA[<p>Personally I always use a different solution (of course it adds to stack bloat, but whatever) but it has served me well in programming competitions. Also the compiler wont catch it if you make a call to f without using the parameter recursionDepth, which can lead to annoying bugs. However default parameters never bit in this case, because I pretty much always have a depth in there.</p>
<p>void f(int recursionDepth = 0)<br />
{<br />
    ++recursionDepth;    </p>
<p>    printf( &#8220;Recursion depth is: %dn&#8221;, recursionDepth );<br />
    // Lots of code here; for each return path, don&#8217;t forget<br />
    // to decrement recursionDepth!    </p>
<p>}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: rix</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-173</link>
		<dc:creator>rix</dc:creator>
		<pubDate>Wed, 11 Apr 2007 07:33:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-173</guid>
		<description>I would make use of C99's __func__ , or __PRETTY_FUNCTION__ (GCC only, but how useful) from a macro, something like:

class RecursionCounter
{
public:
  inline RecursionCounter(string funcname) { counter[funcname]++; }
  ...
private:
  static std::map counter;
};

#define RECURSION_COUNTER RecursionCounter _counter(__func__)

void f()
{
  RECURSION_COUNTER;
  ...
}</description>
		<content:encoded><![CDATA[<p>I would make use of C99&#8217;s __func__ , or __PRETTY_FUNCTION__ (GCC only, but how useful) from a macro, something like:</p>
<p>class RecursionCounter<br />
{<br />
public:<br />
  inline RecursionCounter(string funcname) { counter[funcname]++; }<br />
  &#8230;<br />
private:<br />
  static std::map counter;<br />
};</p>
<p>#define RECURSION_COUNTER RecursionCounter _counter(__func__)</p>
<p>void f()<br />
{<br />
  RECURSION_COUNTER;<br />
  &#8230;<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kblindert</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-167</link>
		<dc:creator>Kblindert</dc:creator>
		<pubDate>Tue, 10 Apr 2007 22:35:16 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-167</guid>
		<description>With some spicy invariants added :)


struct algo
{
 int rcount;
 algo() : rcount(0) {}
 // Recursive alorithm entrypoint
 // Assures algoriithm isn't started yet.
 f() { 
   assert( rcount == 0 );
   f_intern();
   assert( rcount == 0 );
 }
private:
 struct reclvl { 
     reclvl(int&#38; _r) : r(++_r) {}
     ~reclvl() { --r; }
    int level() const { return r; }
    private:
    int&#38; r;
 };
 f_intern()
 {
     reclvl( a_rcount );

     do_stuff().

 }
};</description>
		<content:encoded><![CDATA[<p>With some spicy invariants added <img src='http://blog.froglogic.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>struct algo<br />
{<br />
 int rcount;<br />
 algo() : rcount(0) {}<br />
 // Recursive alorithm entrypoint<br />
 // Assures algoriithm isn&#8217;t started yet.<br />
 f() {<br />
   assert( rcount == 0 );<br />
   f_intern();<br />
   assert( rcount == 0 );<br />
 }<br />
private:<br />
 struct reclvl {<br />
     reclvl(int&amp; _r) : r(++_r) {}<br />
     ~reclvl() { &#8211;r; }<br />
    int level() const { return r; }<br />
    private:<br />
    int&amp; r;<br />
 };<br />
 f_intern()<br />
 {<br />
     reclvl( a_rcount );</p>
<p>     do_stuff().</p>
<p> }<br />
};</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anonymous</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-162</link>
		<dc:creator>Anonymous</dc:creator>
		<pubDate>Tue, 10 Apr 2007 21:56:08 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-162</guid>
		<description>what about passing a ref on the counter to the class (int's just here to increment the value;

class incrementor {
public:
  incrementor(int&#38; i) : m_i(i) {m_i++;}
  ~incrementor() {m_i--;}
  int&#38; m_i;
}

and the function is

void f() {
  static int recursionDepth=0;
  incrementor incr(recursionDepth);

  printf( "Recursion depth: %d\n", recursionDepth );
}</description>
		<content:encoded><![CDATA[<p>what about passing a ref on the counter to the class (int&#8217;s just here to increment the value;</p>
<p>class incrementor {<br />
public:<br />
  incrementor(int&amp; i) : m_i(i) {m_i++;}<br />
  ~incrementor() {m_i&#8211;;}<br />
  int&amp; m_i;<br />
}</p>
<p>and the function is</p>
<p>void f() {<br />
  static int recursionDepth=0;<br />
  incrementor incr(recursionDepth);</p>
<p>  printf( &#8220;Recursion depth: %d\n&#8221;, recursionDepth );<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Anonymous</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-160</link>
		<dc:creator>Anonymous</dc:creator>
		<pubDate>Tue, 10 Apr 2007 17:20:52 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-160</guid>
		<description>You could try using Boost.Fusion's compile-time map using 

class MY_F_COUNTER;
class MY_G_COUNTER;
...

as keys to get at the run-time counters.</description>
		<content:encoded><![CDATA[<p>You could try using Boost.Fusion&#8217;s compile-time map using </p>
<p>class MY_F_COUNTER;<br />
class MY_G_COUNTER;<br />
&#8230;</p>
<p>as keys to get at the run-time counters.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adam</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-159</link>
		<dc:creator>Adam</dc:creator>
		<pubDate>Tue, 10 Apr 2007 14:58:17 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-159</guid>
		<description>@Gregor

The article says: "I’ve been touching this function which happens to call itself recursively and found that in order to add some feature, I needed to know how deeply I recursed into the function already."

I assumed the features were application features and therefore this was not a debug only discussion.

I was thinking more of speed cost than memory cost. That's why I used alpha-beta serach as my example.

It would perhaps be interesting to know why the OP thinks he needs to know where he is in the call stack in order to add his feature.

PS. I hate the captcha. It takes me about 3 tries to post.</description>
		<content:encoded><![CDATA[<p>@Gregor</p>
<p>The article says: &#8220;I’ve been touching this function which happens to call itself recursively and found that in order to add some feature, I needed to know how deeply I recursed into the function already.&#8221;</p>
<p>I assumed the features were application features and therefore this was not a debug only discussion.</p>
<p>I was thinking more of speed cost than memory cost. That&#8217;s why I used alpha-beta serach as my example.</p>
<p>It would perhaps be interesting to know why the OP thinks he needs to know where he is in the call stack in order to add his feature.</p>
<p>PS. I hate the captcha. It takes me about 3 tries to post.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Gregor</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-155</link>
		<dc:creator>Gregor</dc:creator>
		<pubDate>Tue, 10 Apr 2007 14:36:40 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-155</guid>
		<description>@Adam i thought this stuff will only be used in a debug enviroment, this why i thought performance wasn't that critical.

"The problem with the map based solutions is that you have to lookup your void* at each call, that could get expensive depending on the size of the task and how many functions you are counting."
if this isn't used in an embedded system, you will never get so many recursive functions, that memory size could get a problem. we are talking about less than 10bytes per function. you will need more memory to save all your breakpoints...
the execution-time isn't that worse, since the function-pointer is known at compiletime, so there is no lookup needed. it will only pass an int as ctor argument.</description>
		<content:encoded><![CDATA[<p>@Adam i thought this stuff will only be used in a debug enviroment, this why i thought performance wasn&#8217;t that critical.</p>
<p>&#8220;The problem with the map based solutions is that you have to lookup your void* at each call, that could get expensive depending on the size of the task and how many functions you are counting.&#8221;<br />
if this isn&#8217;t used in an embedded system, you will never get so many recursive functions, that memory size could get a problem. we are talking about less than 10bytes per function. you will need more memory to save all your breakpoints&#8230;<br />
the execution-time isn&#8217;t that worse, since the function-pointer is known at compiletime, so there is no lookup needed. it will only pass an int as ctor argument.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Adam</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-153</link>
		<dc:creator>Adam</dc:creator>
		<pubDate>Tue, 10 Apr 2007 14:34:14 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-153</guid>
		<description>I agree, the f_impl() solution is unworkable if f calls g calls f....

But your point about member functions is lost on me. It seems to me that no matter where you hide your static variable, you are only going to have one of them per member function. But this would only matter if you had recursive objects, i.e a.f() calls b.f() calls a.f().... I think this would be a rare case.

If this rare case matters to you then you need some sort of support for reflection. then you could look up the object and the member function (and context?) and update that specific counter.</description>
		<content:encoded><![CDATA[<p>I agree, the f_impl() solution is unworkable if f calls g calls f&#8230;.</p>
<p>But your point about member functions is lost on me. It seems to me that no matter where you hide your static variable, you are only going to have one of them per member function. But this would only matter if you had recursive objects, i.e a.f() calls b.f() calls a.f()&#8230;. I think this would be a rare case.</p>
<p>If this rare case matters to you then you need some sort of support for reflection. then you could look up the object and the member function (and context?) and update that specific counter.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: atomopawn</title>
		<link>http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-151</link>
		<dc:creator>atomopawn</dc:creator>
		<pubDate>Tue, 10 Apr 2007 14:33:17 +0000</pubDate>
		<guid isPermaLink="false">http://blog.froglogic.com/2007/04/recursion-depth-counting/#comment-151</guid>
		<description>Oops.  The article I mentioned is &lt;a HREF="http://www.linuxjournal.com/article/6391" rel="nofollow"&gt;here&lt;/A&gt;.  Sorry 'bout that.</description>
		<content:encoded><![CDATA[<p>Oops.  The article I mentioned is <a HREF="http://www.linuxjournal.com/article/6391" rel="nofollow">here</a>.  Sorry &#8217;bout that.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
