<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Vincent Gable's Blog &#187; Debugging</title>
	<atom:link href="http://vgable.com/blog/tag/debugging/feed/" rel="self" type="application/rss+xml" />
	<link>http://vgable.com/blog</link>
	<description>my weblog.</description>
	<lastBuildDate>Tue, 29 Nov 2011 22:20:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The Most Useful Objective-C Code I&#8217;ve Ever Written</title>
		<link>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/</link>
		<comments>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/#comments</comments>
		<pubDate>Thu, 19 Aug 2010 10:01:01 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[LOG_EXPR]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[Preprocessor]]></category>
		<category><![CDATA[printf]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=670</guid>
		<description><![CDATA[Actually, it&#8217;s the most useful code I&#8217;ve extended; credit for the core idea goes to Dave Dribin with his Handy NSString Conversion Macro. LOG_EXPR(x) is a macro that prints out x, no matter what type x is, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as [...]]]></description>
			<content:encoded><![CDATA[<p>Actually, it&#8217;s the most useful code I&#8217;ve <em>extended</em>; credit for the core idea goes to <a href="http://www.dribin.org/dave/">Dave Dribin</a> with his <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"><cite>Handy NSString Conversion Macro</cite></a>.</p>
<p><strong><code><a href="">LOG_EXPR</a>(x)</code> is a macro that prints out <code>x</code>, no matter what type <code>x</code> is</strong>, without having to worry about format-strings (and related crashes from eg. printing a C-string the same way as an <code>NSString</code>). It works on Mac OS X and iOS. Here are some examples,</p>
<p><code>LOG_EXPR(self.window.screen);</code></p>
<blockquote><p>self.window.screen = &lt;UIScreen: 0x6d20780; bounds = {{0, 0}, {320, 480}}; mode = &lt;UIScreenMode: 0x6d20c50; size = 320.000000 x 480.000000&gt;&gt;
</p></blockquote>
<p><code>LOG_EXPR(self.tabBarController.viewControllers);</code></p>
<blockquote><p>self.tabBarController.viewControllers = (<br />
    &#8220;&lt;UINavigationController: 0xcd02e00&gt;&#8221;,<br />
    &#8220;&lt;SavingsViewController: 0xcd05c40&gt;&#8221;,<br />
    &#8220;&lt;SettingsViewController: 0xcd05e90&gt;&#8221;<br />
)</p></blockquote>
<p>Pretty straightforward, really. The biggest convenience so far is having the expression printed out, so you don&#8217;t have to write out a name redundantly in the format string (eg. <code> NSLog(@"actionURL = %@", actionURL)</code>). But <code>LOG_EXPR</code> really shows it&#8217;s worth when you start using scalar or <code>struct</code> expressions:</p>
<p><code>LOG_EXPR(self.window.windowLevel);</code></p>
<blockquote><p>self.window.windowLevel = 0.000000</p></blockquote>
<p><code>LOG_EXPR(self.window.frame.size);</code></p>
<blockquote><p>self.window.frame.size = {320, 480}</p></blockquote>
<p>Yes, there are expressions that won&#8217;t work, but they&#8217;re pretty rare for me. I use <code>LOG_EXPR</code> every day. Several times. It&#8217;s not quite as good as having <a href="http://vgable.com/blog/2010/06/14/ask-f-script/">a REPL for Cocoa</a>, but it&#8217;s handy.</p>
<p><a href="#Get_LOG_EXPR">Give it a try</a>.</p>
<h3>How It Works</h3>
<p>The problem is how to pick a function or format string to print <code>x</code>, based on the type of <code>x</code>. C++&#8217;s type-based dispatch would be a good fit here, but it&#8217;s verbose (a full function-definition per type) and I wanted to use pure Objective-C if possible. Fortunately, <strong>Objective-C has an <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html"><code>@encode()</code></a>  compiler directive that returns a string describing any type it&#8217;s given.</strong> Unfortunately it works on <em>types</em>, not variables, but with C99 <strong>the <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> compiler directive lets us get the type of any variable</strong>, which we can pass to <code>@encode()</code>.  The final bit of compiler magic is using <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringification (<code>#</code>)</a> to print out the literal string inside <code>LOG_EXPR()</code>&#8216;s parenthesis.</p>
<h3>The Macro, Line By Line</h3>
<div class="code-box">
<pre>
1 #define LOG_EXPR(_X_) do{\
2 	__typeof__(_X_) _Y_ = (_X_);\
3 	const char * _TYPE_CODE_ = @encode(__typeof__(_X_));\
4 	NSString *_STR_ = VTPG_DDToStringFromTypeAndValue(_TYPE_CODE_, &#038;_Y_);\
5 	if(_STR_)\
6 		NSLog(@"%s = %@", #_X_, _STR_);\
7 	else\
8 		NSLog(@"Unknown _TYPE_CODE_: %s for expression %s in function %s, file %s, line %d", _TYPE_CODE_, #_X_, __func__, __FILE__, __LINE__);\
9 }while(0)
</pre>
</div>
<ol>
<li>The first and last lines are a way to put <code>{}</code>&#8216;s around the macro to prevent <a href="http://en.wikipedia.org/wiki/C_preprocessor#Multiple_statements">unintended effects</a>. The <code>do{}while(0);</code> &#8220;loop&#8221; does nothing else.</li>
<li>First evaluate the expression, <code>_X_</code>, given to <code>LOG_EXPR</code> <em>once</em>, and store the result in a <code>_Y_</code>. We need to use <code><a href="http://gcc.gnu.org/onlinedocs/gcc/Typeof.html">typeof()</a></code> (which had to be written <code>__typeof__()</code> to appease some versions of GCC) to figure out the type of <code>_Y_</code>.</li>
<li><code>_TYPE_CODE_</code> is c-string that <a href="http://developer.apple.com/mac/library/documentation/cocoa/conceptual/ObjCRuntimeGuide/Articles/ocrtTypeEncodings.html">describes the type</a> of the expression we want to print out.</li>
<li>Now we have enough information to call a function, <code>VTPG_DDToStringFromTypeAndValue()</code> to convert the expression&#8217;s value to a string. We pass it the <code>_TYPE_CODE_</code> string, and <em>the address of </em> <code>_Y_</code>, which is a pointer, and has a known size. We can&#8217;t pass <code>_Y_</code> directly, because depending on what <code>_X_</code> is, it will have different types and could be of any size.</li>
<li><code>VTPG_DDToStringFromTypeAndValue()</code> returns <code>nil</code> if it can&#8217;t figure out how to convert a value to a string.</li>
<li>Everything went well, print the <a href="http://gcc.gnu.org/onlinedocs/cpp/Stringification.html">stringified</a> expression, <code>#_X_</code>, and  the string representing it&#8217;s value, <code>_STR_</code>.</li>
<li>otherwise…</li>
<li>The expression had a type we can&#8217;t handle, print out a verbose diagnostic message.</li>
<li>See line 1.</li>
</ol>
<h3>The <code>VTPG_DDToStringFromTypeAndValue()</code> Function</h3>
<p>See the source in <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a>:</p>
<p><iframe src ="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m" width="100%" height="300">(Your browser does not support iframes.)</iframe></p>
<p>It&#8217;s derived from  <a href="http://www.dribin.org/dave/">Dave Dribin</a>&#8216;s function <a href="http://www.dribin.org/dave/blog/archives/2008/09/22/convert_to_nsstring/"> <code>DDToStringFromTypeAndValue()</code></a>, and is pretty straightforward: <code>strcmp()</code> the type-string, and if it matches a known type call a function, or use <code>+[NSString stringWithFormat]:</code>, to turn the value into a string.</p>
<h3>The First Step Twords Fixing Your Macro Problem is Admitting it&#8230;</h3>
<p>So yeah, maybe I went a little wild with macros here…</p>
<p>But it took out some <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">WET</a>-ness of the original code, and prevents me from accidentally mixing up types in a long wall of <code>if</code>s, eg.</p>
<div class="code-box">
<pre>
else if (strcmp(typeCode, @encode(NSRect)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
else if (strcmp(typeCode, @encode(NSRange)) == 0)
{
    return NSStringFromRect(*(NSRange *)value);
}
</pre>
</div>
<p>If I were cool, I&#8217;d use <code>NSDictionary</code>s to map from the <code>@encode</code>-string to an appropriate format string or function pointer.  This is conceptually cleaner; less error-prone than using macros; and almost certainly faster. Unfortunately, it gets a little tricky with functions, since I need to deference <code>value</code> into the proper type.</p>
<p>One final note from my testing, I could do away with the <code>strcmp()</code>s, because directly comparing <code>@encode</code> string pointers (eg <code>if(typeCode == @encode(NSString*))</code> works. I don&#8217;t know if it will <em>always</em> work though, so relying on it strikes me as a profoundly Bad Idea. But maybe that bad idea will give someone a good idea.</p>
<h3>Limitations</h3>
<h4>Arrays</h4>
<p>C arrays generally muck things up. Casting to a pointer works around this:</p>
<div class="code-box">
<pre>
char x[14] = "Hello, world!";
//LOG_EXPR(x); //error: invalid initializer
LOG_EXPR((char*)x); //prints fine
</pre>
</div>
<h4><code>__func__</code></h4>
<p>Because it is a <code>static const char []</code>, <code><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1642.html">__func__</a></code> (and <code>__FUNCTION__</code> or <code>__PRETTY_FUNCTION__</code>) need casting to <code>char*</code> to work with <code>LOG_EXPR</code>. Because logging out a function/method call is something I do frequently, I use the macro:</p>
<div class="code-box">
<pre>
#define LOG_FUNCTION()	NSLog(@"%s", __func__)</pre>
</div>
<h4><code>long double</code> (Leopard and older)</h4>
<p>On older systems, <code>LOG_EXPR</code> won&#8217;t work with a <code>long double</code> value, because <code>@encode(long double)</code> gives the same result as <code>@encode(double)</code>. This is a <a href="http://openradar.appspot.com/6468314">known issue</a> with the runtime. The top-level <code>LOG_EXPR</code> macro could detect a <code>long double</code> with <code>if((sizeof(_X_) == sizeof(long double)) &#038;&#038; (_TYPE_CODE_ == @encode(double)))</code>. But I doubt this will ever be necessary.</p>
<p>I haven&#8217;t actually written any code that uses <code>long double</code>, because I <strong>use <code><a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/doc/uid/20000055-BCIHCEFJ">NSDecimal</a></code>, or another base-10 number format, for situations that require more precision than a <code>double</code>.</strong></p>
<h3>Scaling and Frameworks </h3>
<p>Growing <code>LOG_EXPR</code> to handle <em>every</em> type is a lot of work. I&#8217;ve only added types that I&#8217;ve actually needed to print. This has kept the code manageable, and seems to be working so far.</p>
<p>The biggest problem I have is <strong>how to deal with types that are in frameworks that not every project includes</strong>. Projects that use CoreLocation.framework need to be able to use <code>LOG_EXPR</code> to print out CoreLocation specific <code>struct</code>s, like <code> CLLocationCoordinate2D</code>. But projects that <em>don&#8217;t</em> use CoreLocation.framework don&#8217;t have a definition of the <code>CLLocationCoordinate2D</code> type, so code to convert it to a string won&#8217;t compile. There are two ways I&#8217;ve tried to solve the problem</p>
<h4>Comment-out framework-specific code</h4>
<p>This is pretty self-explanatory, I&#8217;ll fork VTPG_Common.m and un-comment-out code for types that my project needs to print. It works, but it&#8217;s drudgery. Programmers hate that.</p>
<h4>Hardcode type info</h4>
<p>The idea is to hard-code the string that <code>@encode(SomeType)</code> would evaluate to, and then (since we know how <code>SomeType</code> is laid out in memory) use casting and pointer-arithmetic to get at the fields.</p>
<p>For example:</p>
<div class="code-box">
<pre>
//This is a hack to print out CLLocationCoordinate2D, without needing to #import &lt;CoreLocation/CoreLocation.h&gt;
//A CLLocationCoordinate2D is a struct made up of 2 doubles.
//We detect it by hard-coding the result of @encode(CLLocationCoordinate2D).
//We get at the fields by treating it like an array of doubles, which it is identical to in memory.
if(strcmp(typeCode, "{?=dd}")==0)//@encode(CLLocationCoordinate2D)
	return [NSString stringWithFormat:@"{latitude=%g,longitude=%g}",((double*)value)[0],((double*)value)[1]];
</pre>
</div>
<p>This Just Works in a project that includes CoreLocation, and doesn&#8217;t mess up projects that don&#8217;t. Unfortunately it&#8217;s <em>horribly brittle</em>. Any Xcode or system update could break it. It&#8217;s not a tenable fix.</p>
<h3>Areas for Improvement</h3>
<p>If there&#8217;s some type <code>LOG_EXPR</code> can&#8217;t handle that you need, please <a href="http://github.com/VTPG/CommonCode">jump right in and improve it</a>!</p>
<p>When I have time, I plan to write a general parser for <code>@encode()</code>-strings. This will let me print out <em>any</em> <code>struct</code>, which mostly solves the type-defined-in-missing-framework problem, and would let <code>LOG_EXPR</code> Just Work with types from all kinds of POSIX/C libraries.</p>
<h3><a name="Get_LOG_EXPR"></a>Using <code>LOG_EXPR()</code> in Your Project </h3>
<p>Download <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.m">VTPG_Common.m</a> and <a href="http://github.com/VTPG/CommonCode/blob/master/VTPG_Common.h">VTPG_Common.h</a> from <a href="http://github.com/VTPG/CommonCode">my github repository</a>, and add them to your Xcode project.</p>
<p>Now just add the line <code>#import "VTPG_Common.h"</code> to your prefix file (named <code>&lt;ProjectName&gt;_Prefix.pch</code> by default), after the <code>#ifdef __OBJC__</code>, for example:</p>
<div class="code-box">
<pre>
#ifdef __OBJC__
    #import &lt;Foundation/Foundation.h&gt;
    // maybe other files, depending on project  template...
    #import "VTPG_Common.h"
#endif</pre>
</div>
<p>Now <code>LOG_EXPR()</code> will work everywhere in your project.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/08/19/the-most-useful-objective-c-code-ive-ever-written/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>What Am I About To Call?</title>
		<link>http://vgable.com/blog/2010/04/29/what-am-i-about-to-call/</link>
		<comments>http://vgable.com/blog/2010/04/29/what-am-i-about-to-call/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 02:40:10 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Reverse Engineering]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[gdb]]></category>
		<category><![CDATA[x86]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=597</guid>
		<description><![CDATA[Say you&#8217;re in gdb, and about to execute a call instruction for dyld_stub_objc_msgSend, how do you know what&#8217;s about to happen? On i386 (gdb) x/s *(SEL*)($esp+4) tells you the message that&#8217;s about to be sent. (gdb) po *(id*)$esp tells you the target object that&#8217;s about to get the message.]]></description>
			<content:encoded><![CDATA[<p>Say you&#8217;re in gdb, and about to execute a <code>call</code> instruction for <code>dyld_stub_objc_msgSend</code>, how do you know what&#8217;s about to happen?</p>
<h3>On i386</h3>
<pre>(gdb) x/s *(SEL*)($esp+4)</pre>
<p>tells you the <strong>message</strong> that&#8217;s about to be sent.</p>
<pre>(gdb) po *(id*)$esp</pre>
<p>tells you the <strong>target</strong> object that&#8217;s about to get the message.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2010/04/29/what-am-i-about-to-call/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Check malloc()</title>
		<link>http://vgable.com/blog/2009/10/12/dont-check-malloc/</link>
		<comments>http://vgable.com/blog/2009/10/12/dont-check-malloc/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 01:25:21 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quotes]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[malloc]]></category>
		<category><![CDATA[Mike Ash]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/?p=434</guid>
		<description><![CDATA[There&#8217;s no point in trying to recover from a malloc failure on OS X, because by the time you detect the failure and try to recover, your process is likely to already be doomed. There&#8217;s no need to do your own logging, because malloc itself does a good job of that. And finally there&#8217;s no [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>There&#8217;s no point in trying to recover from a <code>malloc</code> failure on OS X, because by the time you detect the failure and try to recover, your process is likely to already be doomed. There&#8217;s no need to do your own logging, because <code>malloc</code> itself does a good job of that. And finally there&#8217;s no real need to even explicitly abort, because any <code>malloc</code> failure is virtually guaranteed to result in an instantaneous crash with a good stack trace.</p></blockquote>
<p>&#8211;<a href="http://www.mikeash.com/?page=pyblog/friday-qa-2009-10-09-defensive-programming.html">Mike Ash</a></p>
<p>This is <em>excellent advice</em>. Peppering your code with <code>if</code> statements harms readability and simplicity.</p>
<p>It&#8217;s still a good idea to check large (many MB) <code>malloc</code>s, but I can&#8217;t imagine recovering gracefully from a situation where 32 byte memory allocations are failing on a modern desktop.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2009/10/12/dont-check-malloc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catching nil Member Variables</title>
		<link>http://vgable.com/blog/2008/12/12/catching-nil-member-variables/</link>
		<comments>http://vgable.com/blog/2008/12/12/catching-nil-member-variables/#comments</comments>
		<pubDate>Sat, 13 Dec 2008 03:48:27 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[nil]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Unit Testing]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/12/12/catching-nil-member-variables/</guid>
		<description><![CDATA[When I wrote this method it seemed like it would be helpful, //log a warning for any member variable that nil - (void) warnOfNilIVars; { &#160;&#160;unsigned int ivarCount = 0; &#160;&#160;Ivar * ivarList = class_copyIvarList([self class], &#038;ivarCount); &#160;&#160;if(ivarList) { &#160;&#160;&#160;&#160;for(int i = 0; i < ivarCount; i++){ &#160;&#160;&#160;&#160;&#160;&#160;const char *typeString = ivar_getTypeEncoding(ivarList[i]); &#160;&#160;&#160;&#160;&#160;&#160;if(typeString &#038;&#038; typeString[0] [...]]]></description>
			<content:encoded><![CDATA[<p>When I wrote this method it seemed like it would be helpful,</p>
<p><code>//log a warning for any member variable that nil<br />
- (void) warnOfNilIVars;<br />
{<br />
&nbsp;&nbsp;unsigned int ivarCount = 0;<br />
&nbsp;&nbsp;Ivar * ivarList = class_copyIvarList([self class], &#038;ivarCount);<br />
&nbsp;&nbsp;if(ivarList) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;for(int i = 0; i < ivarCount; i++){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const char *typeString = ivar_getTypeEncoding(ivarList[i]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(typeString &#038;&#038; typeString[0] == '@')<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(!object_getIvar(self, ivarList[i]))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NSLog(@"***WARNING: ivar %s of %@ is nil", ivar_getName(ivarList[i]), [self className]);<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;free(ivarList);<br />
&nbsp;&nbsp;}<br />
}<br /></code></p>
<p>But in practice I haven&#8217;t really used it (and when I have there were quite a few false-positives).  Still, I think it&#8217;s pretty neat that you can do something like this in Objective-C.</p>
<p>If you find a use for it, please let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/12/12/catching-nil-member-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NSAssert Considered Harmful</title>
		<link>http://vgable.com/blog/2008/12/04/nsassert-considered-harmful/</link>
		<comments>http://vgable.com/blog/2008/12/04/nsassert-considered-harmful/#comments</comments>
		<pubDate>Thu, 04 Dec 2008 11:03:39 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Bug Bite]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[assert]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[NSAssert]]></category>
		<category><![CDATA[NSCAssert]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/12/04/nsassert-considered-harmful/</guid>
		<description><![CDATA[The NSAssert() function is unreliable, and therefore dangerous. Plain-old assert() is a better choice. Note that #define NDEBUG disables assert(); and #define NS_BLOCK_ASSERTIONS disables NSAssert(). One kind of assert being disabled does not mean the other kind is. Nether kind of assertion is disabled by default when building in &#8220;Release&#8221; mode &#8212; you must be [...]]]></description>
			<content:encoded><![CDATA[<p>The <code><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/c/func/NSAssert">NSAssert()</a></code> function is unreliable, and therefore dangerous.  <strong>Plain-old <code><a href="http://en.wikipedia.org/wiki/Assert.h">assert()</a></code> is a better choice.</strong></p>
<p>Note that <code>#define NDEBUG</code> disables <code>assert()</code>; and <code>#define NS_BLOCK_ASSERTIONS</code> disables <code>NSAssert()</code>. One kind of assert being disabled does not mean the other kind is.  Nether kind of assertion is disabled by default when building in &#8220;Release&#8221; mode &#8212; you must be sure to disable them yourself.  Be careful, a user will not appreciate the difference between a bug and a failed assertion &#8212; both are a crash.  </p>
<p><code>assert()</code> <em>immediately</em> stops your program with a <code>SIGABORT</code> signal.  You can&#8217;t miss a failed <code>assert()</code>, its behavior is predictable, and it <a href="http://martinfowler.com/ieeeSoftware/failFast.pdf">fails fast (link is a PDF)</a>.</p>
<p>But a failed <code>NSAssert()</code> behaves unpredictably.  Sometimes it stops program execution, sometimes it does not and leaves the program in a strange inconsistent state.  I have entirely missed <code>NSAssert()</code>s failing, because I did not look at the console.  <code>if(!expr) NSLog();</code> would have been a better choice in the those cases, because at least I would have known how it behaved.</p>
<p><a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSAssertionHandler_Class/Reference/Reference.html">According to Apple</a>,</p>
<blockquote><p> Assertion macros, such as NSAssert and NSCAssert &#8230; pass a string to an <code>NSAssertionHandler</code> object describing the failure. Each thread has its own <code>NSAssertionHandler</code> object. When invoked, an assertion handler prints an error message that includes the method and class (or function) containing the assertion and raises an <code>NSInternalInconsistencyException</code>.</p></blockquote>
<p>Complicated!  The complexity means it is possible to <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSAssertionHandler_Class/Reference/Reference.html">customize what happens when an <code>NSAssert()</code> fails</a>.  That sounds cool, but I&#8217;ve never heard of someone needing to actually <em>do</em> that.  </p>
<p>If a framework catches <code>NSInternalInconsistencyException</code>s, then your program will keep right on running after a failed <code>NSAssert()</code>.  I have had this happen to me several times.  I apologize for not having taken the time to investigate what frameworks were catching what.</p>
<p>Apple could change what catches what with any software update.</p>
<p>Variability and complexity are the last things you want while debugging.  There&#8217;s no reason to invite it them by using <code>NSAssert()</code> over <code>assert()</code>.  Since <code>NSAssert()</code> is <em>not</em> guaranteed to stop your program, it can not be relied on to guard against <a href="http://vgable.com/blog/2008/12/11/there-are-worse-things-than-crashing/">data corruption, or anything worse then a predictable crash.</a></p>
<p>UPDATE 2009-06-01: You can annotate <code>assert()</code>, so it prints an explanation like <code>NSAssert()</code>, by <code>&#038;&#038;</code>ing in a string after the condition. For example <code>assert(i &lt; j)</code> is a <em>lot</em> more useful with an explanation: <code>assert(i &lt; j &#038;&#038; "unexpected cycle in graph")</code> &#8212; on failure it prints </p>
<blockquote><p>Assertion failed: (i &lt; j &#038;&#038; &#8220;unexpected cycle in graph&#8221;), function WillHalt(), file /path/to/code.m, line 30.
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/12/04/nsassert-considered-harmful/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Bug In The Machine</title>
		<link>http://vgable.com/blog/2008/12/02/bug-in-the-machine/</link>
		<comments>http://vgable.com/blog/2008/12/02/bug-in-the-machine/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 02:43:28 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Announcement]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Reverse Engineering]]></category>
		<category><![CDATA[Bugs]]></category>
		<category><![CDATA[Cosmic Coincidence]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Very Cool]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/12/02/bug-in-the-machine/</guid>
		<description><![CDATA[I was going through some old (OS 9 old at youngest!) backups, and found this dump from a MacsBug session. You can actually see a bug sitting in memory! To me it looks like the bug is inside an old television, with distortion sweeping across the screen, so some of the bug&#8217;s left side is [...]]]></description>
			<content:encoded><![CDATA[<p>I was going through some old (<a href="http://en.wikipedia.org/wiki/Mac_OS_9">OS 9</a> old at youngest!) backups, and found this dump from a <a href="http://developer.apple.com/tools/debuggers/MacsBug/">MacsBug</a> session.  <strong>You can actually see a bug sitting in memory</strong>!  To me it looks like the bug is inside an old television, with distortion sweeping across the screen, so some of the bug&#8217;s left side is wrapped around to the right.</p>
<p><code>&nbsp;Displaying&nbsp;memory&nbsp;from&nbsp;1D9F8CB0<br />&nbsp;&nbsp;1D9F8CB0&nbsp;&nbsp;•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???<br />&nbsp;&nbsp;1D9F8CF0&nbsp;&nbsp;•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???<br />&nbsp;&nbsp;1D9F8D30&nbsp;&nbsp;•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???•???<br />&nbsp;&nbsp;1D9F8D70&nbsp;&nbsp;•???•???•???•???•üÖ`´••••••P•••Ñ•y•pÄ@•••••Ä•@•••••••••H•••H••••<br />&nbsp;&nbsp;1D9F8DB0&nbsp;&nbsp;•••••••••••É9ÿ•••••••••••••••••••üçÄ´•••••&nbsp;•••‚&nbsp;0000000000000000<br />&nbsp;&nbsp;1D9F8DF0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8E30&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8E70&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8EB0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8EF0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8F30&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F8F70&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000%***$*#**<br />&nbsp;&nbsp;1D9F8FB0&nbsp;&nbsp;#*$$*$*#*#**$$*00*$*$*$$**#*#*#*#*#*#**#%00000000000000*•!#•!!!!<br />&nbsp;&nbsp;1D9F8FF0&nbsp;&nbsp;!!!•!!!!!!!!!!!0%!!!!#!!!!!!!!!!!!!!!!!!*00000000000000*!"!•!!!!<br />&nbsp;&nbsp;1D9F9030&nbsp;&nbsp;!!••!!!!!!!!!!!0.!!••!!!!!!!!!!•!•!!•!!!#00000000000000*!!!(•!!!<br />&nbsp;&nbsp;1D9F9070&nbsp;&nbsp;!!!(•!!!!!!!!!!0%!!((!!!!!!!!•!!!!!!!!!!*00000000000000#!!!&nbsp;••!&nbsp;<br />&nbsp;&nbsp;1D9F90B0&nbsp;&nbsp;•••••••••••••••0*••!•••••••••••••••••••••00000000000000*!!!•••00<br />&nbsp;&nbsp;1D9F90F0&nbsp;&nbsp;•••••••••••••••0#••!•••••••••••!00•••••••00000000000000#!!!••#0/<br />&nbsp;&nbsp;1D9F9130&nbsp;&nbsp;0&#038;••••••••••••••!••!&nbsp;•••••••••+0$0.••••••00000000000000#!!!•!0••<br />&nbsp;&nbsp;1D9F9170&nbsp;&nbsp;!00#••••••••!000000$!•••••••!00!••,•••••&nbsp;00000000000000*!!!•0%••<br />&nbsp;&nbsp;1D9F91B0&nbsp;&nbsp;••%0%••••••%00000000/••••••,0.••••%0•••••00000000000000$!••00•••<br />&nbsp;&nbsp;1D9F91F0&nbsp;&nbsp;••!*00••••000000000000••••00!••••••00#•••00000000000000*!!/0••••<br />&nbsp;&nbsp;1D9F9230&nbsp;&nbsp;••!••/0$•00000000000000••0$••••••••*0%!•!00000000000000#•#0$••••<br />&nbsp;&nbsp;1D9F9270&nbsp;&nbsp;•!•••!$•*00000000000000%•!•••••••!(•*0*•&nbsp;00000000000000*•00••••!<br />&nbsp;&nbsp;1D9F92B0&nbsp;&nbsp;(•••••••0000000000000000•••••••!*&nbsp;•••%0•!00000000000000*00••••!0<br />&nbsp;&nbsp;1D9F92F0&nbsp;&nbsp;&#038;!•••••/00000000000000000!•••'$00!••••00*00000000000000*•*!•••00<br />&nbsp;&nbsp;1D9F9330&nbsp;&nbsp;000••••000000000000000000•!•*00/%0••••••*00000000000000$!•!••$0•<br />&nbsp;&nbsp;1D9F9370&nbsp;&nbsp;••%00•!000000000000000000*$00%!••0#••••••00000000000000$!••••0.•<br />&nbsp;&nbsp;1D9F93B0&nbsp;&nbsp;••••$•%0000000000000000000•%!•••••0!••••!00000000000000*!•(•00••<br />&nbsp;&nbsp;1D9F93F0&nbsp;&nbsp;•••(••00000000000000000000!!&nbsp;•••••/0"••••00000000000000#!!!$0•••<br />&nbsp;&nbsp;1D9F9430&nbsp;&nbsp;••!!••00000000000000000000•!!••••!#0%!•••00000000000000*!!*0*•••<br />&nbsp;&nbsp;1D9F9470&nbsp;&nbsp;••!•••00000000000000000000*!•••("!••0#•••00000000000000*!!0,••••<br />&nbsp;&nbsp;1D9F94B0&nbsp;&nbsp;•!&nbsp;•••00000000000000000000#!•!•!••••/0••&nbsp;00000000000000#!%0!••••<br />&nbsp;&nbsp;1D9F94F0&nbsp;&nbsp;••••••00000000000000000000#•*••••••••0%!!00000000000000*!•$•••%0<br />&nbsp;&nbsp;1D9F9530&nbsp;&nbsp;0000#•00000000000000000000#%00000%•••!•!•00000000000000*!!!••!0%<br />&nbsp;&nbsp;1D9F9570&nbsp;&nbsp;*•!&nbsp;••00000000000000000000*#*$!!•0!•••••*00000000000000*!(!••00!<br />&nbsp;&nbsp;1D9F95B0&nbsp;&nbsp;••••••00000000000000000000••!!•••/0•••••#00000000000000#!!!•$0••<br />&nbsp;&nbsp;1D9F95F0&nbsp;&nbsp;••••••%0000000000000000000!(!!••••0%•••••00000000000000*!!!(0*••<br />&nbsp;&nbsp;1D9F9630&nbsp;&nbsp;••!!!!.000000000000000000.!!!••!!!%0-!••!00000000000000*!(•0,•••<br />&nbsp;&nbsp;1D9F9670&nbsp;&nbsp;••!•!•!000000000000000000•#*•••••••,0••••00000000000000$!!$0••••<br />&nbsp;&nbsp;1D9F96B0&nbsp;&nbsp;•!•$00•/00000000000000000•00/*••••••0.!•!00000000000000*!!!!••••<br />&nbsp;&nbsp;1D9F96F0&nbsp;&nbsp;#000•••!0000000000000000$(•.00%•••••&nbsp;•!!•00000000000000*!!••••••<br />&nbsp;&nbsp;1D9F9730&nbsp;&nbsp;00!•••••/000000000000000!!(!!*00••••••&nbsp;!•00000000000000$!!(••••$<br />&nbsp;&nbsp;1D9F9770&nbsp;&nbsp;0•••••••!00000000000000*!!!!!•!0!••••••!$00000000000000#(!!••••0<br />&nbsp;&nbsp;1D9F97B0&nbsp;&nbsp;,••••••!!$000000000000$!!!!!!•!00•••••••$00000000000000*!!!••••0<br />&nbsp;&nbsp;1D9F97F0&nbsp;&nbsp;&nbsp;••••!••••!0000000000$(!!!!!••••0*••••••!00000000000000#!!!•••,/<br />&nbsp;&nbsp;1D9F9830&nbsp;&nbsp;••••!!!•••••00000000*!!!!"!!••••/0••••••!00000000000000*!!!•••0!<br />&nbsp;&nbsp;1D9F9870&nbsp;&nbsp;••••••••••••••$%%%•!!!!!!!!•••••&nbsp;0)••••••00000000000000#!!!••/0•<br />&nbsp;&nbsp;1D9F98B0&nbsp;&nbsp;•••!!•••••••••.,/•(•!!!!!!•••••••0,!!••••00000000000000*!!!••0!•<br />&nbsp;&nbsp;1D9F98F0&nbsp;&nbsp;•••••••••••••00000•!!!!!!••••••••!0!!••••00000000000000#!!!•••••<br />&nbsp;&nbsp;1D9F9930&nbsp;&nbsp;••!!••••••••.000000!!!!!••••••••••••!!••!00000000000000$••!•••••<br />&nbsp;&nbsp;1D9F9970&nbsp;&nbsp;••!•••••••••0000000!•&nbsp;•••••••••••••••!•••00000000000000*!•!•••••<br />&nbsp;&nbsp;1D9F99B0&nbsp;&nbsp;•!!•••••••••0000000$!••••••••••••••••!!•!00000000000000#!!!•••••<br />&nbsp;&nbsp;1D9F99F0&nbsp;&nbsp;•!•••••••••!0000000*!"••••••••••••••••!•&nbsp;00000000000000#!!••••••<br />&nbsp;&nbsp;1D9F9A30&nbsp;&nbsp;••••••••••••0000000#!!••••••••••••••••••!00000000000000#!!!•••••<br />&nbsp;&nbsp;1D9F9A70&nbsp;&nbsp;••••••••••••0000000•!!!••••••••••••••••••00000000000000$!"••••••<br />&nbsp;&nbsp;1D9F9AB0&nbsp;&nbsp;•••••••••••••000000!!!••••••••••••••••••!00000000000000*!!!•••••<br />&nbsp;&nbsp;1D9F9AF0&nbsp;&nbsp;•••••••••••••/0000•(!!!•••••••••••••••••&nbsp;00000000000000#!•!•••••<br />&nbsp;&nbsp;1D9F9B30&nbsp;&nbsp;••••••••••••••!*$•!!!!!••••••••••••••••••00000000000000#!!••••••<br />&nbsp;&nbsp;1D9F9B70&nbsp;&nbsp;••••••••••••••••!!!"!!!••••••••••••••••••00000000000000*!!!•••••<br />&nbsp;&nbsp;1D9F9BB0&nbsp;&nbsp;•••••••••••••••••!!!!!•••••••••••••••••••00000000000000%$#*!!•!&nbsp;<br />&nbsp;&nbsp;1D9F9BF0&nbsp;&nbsp;•!!!••&nbsp;!&nbsp;•!&nbsp;•&nbsp;•&nbsp;!#*$*#!!!•!&nbsp;!!&nbsp;!••&nbsp;!&nbsp;•&nbsp;!*00000000000000000000000<br />&nbsp;&nbsp;1D9F9C30&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9C70&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9CB0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9CF0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9D30&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9D70&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9DB0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9DF0&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9E30&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;&nbsp;1D9F9E70&nbsp;&nbsp;0000000000000000000000000000000000000000000000000000000000000000<br />&nbsp;Unrecognized&nbsp;symbol&nbsp;'prinf'<br />&nbsp;Closing&nbsp;log<br /></code></p>
<p>I swear this is a real memory dump of a sold-for-money application that I didn&#8217;t have any part in writing.  Unfortunately I don&#8217;t remember some specifics, like which application it was.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/12/02/bug-in-the-machine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CFShow is NSLog for Core Foundation Types</title>
		<link>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/</link>
		<comments>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 00:44:52 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[CoreFoundation]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[NSCFType]]></category>
		<category><![CDATA[NSLog]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/</guid>
		<description><![CDATA[CFShow(coreFoundationThingy) will print out a description of coreFoundationThingy to the console. Output looks something like: {value = w:1186.000000 h:687.000000 type = kAXValueCGSizeType} If NSLog() is printing something out as an NSCFType, try CFShow().]]></description>
			<content:encoded><![CDATA[<p><code>CFShow(coreFoundationThingy)</code> will print out a description of <code>coreFoundationThingy</code> to the console.  Output looks something like:</p>
<blockquote><p><AXValue 0x159f20> {value = w:1186.000000 h:687.000000 type = kAXValueCGSizeType}</p></blockquote>
<p>If <code>NSLog()</code> is printing something out as an <code>NSCFType</code>, try <code>CFShow()</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/09/27/cfshow-is-nslog-for-core-foundation-types/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>I Would Rather Have a Runtime Error Than a Compile Error</title>
		<link>http://vgable.com/blog/2008/09/18/i-would-rather-have-a-runtime-error-than-a-compile-error/</link>
		<comments>http://vgable.com/blog/2008/09/18/i-would-rather-have-a-runtime-error-than-a-compile-error/#comments</comments>
		<pubDate>Thu, 18 Sep 2008 23:49:11 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Quotes]]></category>
		<category><![CDATA[Reverse Engineering]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[Dynamic Typing]]></category>
		<category><![CDATA[Software Development]]></category>
		<category><![CDATA[Static Typing]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/09/18/i-would-rather-have-a-runtime-error-than-a-compile-error/</guid>
		<description><![CDATA[And the weird thing is, I realized early in my career that I would actually rather have a runtime error than a compile error. [(some laughs)] Because at that time&#8230; now this is way contrary to popular opinion. Everybody wants early error detection. Oh God, not a runtime error, right? But the debugger gives you [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>And the weird thing is, I realized early in my career that I would actually rather have a runtime error than a compile error. [(<em>some laughs</em>)] Because at that time&#8230; now this is way contrary to popular opinion. Everybody wants early error detection. Oh God, not a runtime error, right? But the debugger gives you this ability to start poking and prodding, especially in a more dynamic language, where you can start simulating things, you can back it up&#8230; You&#8217;ve got your time-machine debuggers like the OCaml one, that can actually save the states and back up.</p>
<p>You&#8217;ve got amazing tools at your disposal (in the debugger)&#8230; Whereas if the compiler gives you an error that says &#8220;expected expression angle-bracket&#8221;, you don&#8217;t have a &#8220;compiler-debugger&#8221; that you can shell into&#8230;</p>
<p><strong>So, you know, in some sense, your runtime errors are actually kind of nicer.</strong></p></blockquote>
<p>&#8211; An excerpt from <a href="http://steve-yegge.blogspot.com/2008/05/dynamic-languages-strike-back.html">one of Steve Yegge&#8217;s (long!) talks</a>.</p>
<p>I think there is a real nugget of truth in this.  At runtime, you can examine your program&#8217;s <em>state</em>, but there is absolutely no way to do that at compile time.  Without a debugger, you can&#8217;t just look at some nontrivial code and <em>know</em> what the value of <code>x</code> is when there&#8217;s an error reading <code>y</code>.  (Adding <code>"print x"</code>, recompiling, and trying again, would work of course, but that&#8217;s just using your compiler as an inefficient debugger!)</p>
<p>Similarly, <em><a href="http://www.mindview.net/WebLog/log-0025">Strong Typing vs. Strong Testing</a> </em>, essentially argues that some tests can only be made at runtime.  (If you read any links on this page, <a href="http://www.mindview.net/WebLog/log-0025">read it</a>, it&#8217;s much shorter and to the point).</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/09/18/i-would-rather-have-a-runtime-error-than-a-compile-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>-description, Little-Known Hero of Debugging</title>
		<link>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/</link>
		<comments>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/#comments</comments>
		<pubDate>Wed, 17 Sep 2008 00:50:33 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[NSLog]]></category>
		<category><![CDATA[NSObject]]></category>
		<category><![CDATA[NSString]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/</guid>
		<description><![CDATA[Or: How to Make NSLog() Useful With Your Objects Say you have an archaically named NSArray that you want to inspect &#8212; it&#8217;s easy to do, since NSLog(@"The bestiary is %@", bestiary); prints out the array&#8217;s contents 2008-09-16 19:46:06.445 Tester[2678:10b] The bestiary is ( Cheetah, Pumpa, Jaguar, Panther, Tiger, Leopard ) But if you try [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Or: How to Make <code>NSLog()</code> Useful With Your Objects</strong></p>
<p>Say you have an archaically named <code>NSArray</code> that you want to inspect &#8212; it&#8217;s easy to do, since <code>NSLog(@"The bestiary is %@", bestiary);</code> prints out the array&#8217;s contents</p>
<blockquote><p>2008-09-16 19:46:06.445 Tester[2678:10b] The bestiary is (<br />
    Cheetah,<br />
    Pumpa,<br />
    Jaguar,<br />
    Panther,<br />
    Tiger,<br />
    Leopard<br />
)
</p></blockquote>
<p>But if you try to <code>NSLog</code> your own object, you get pretty useless output, like<br />
<blockquote>myObject = &lt;MyObject: 0x53f330&gt;</p></blockquote>
<p>Fortunately, it&#8217;s easy to fix!  Just implement the method <a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/description"><code>-(NSString*) description;</code></a> and whatever it returns will be printed by <code>NSLog</code> and GDB (<code>po <em>object</em></code>, will print <em>object</em> in GDB and the Xcode debugging console).</p>
<p>Here&#8217;s an (unfortunately complex) example,<br />
<br /><code>- (NSString*) description;<br />
{<br />
&nbsp;&nbsp;return [NSString stringWithFormat:@"<%@ %p> = {\n\tquestion=%@,\n\tanswer=%@,\n\tsource=%@\n}", [self className], self, self.question, self.answer, self.source];<br />
}<br /></code><br />
output:</p>
<blockquote><p>myObject = &lt;MyObject 0x53eed0&gt; = {<br />
&nbsp;&nbsp;question=What is the Best Thing Ever Of All Times, Ever?,<br />
&nbsp;&nbsp;answer=The Internet!,<br />
&nbsp;&nbsp;source=http://www.cabel.name/2008/01/2007-cabel-yay-awards.html<br />
}</p></blockquote>
<p><strong>Useful Formatters and such</strong></p>
<p><a href="http://vgable.com/blog/2008/08/05/simpler-logging-2/">These macros have made my debugging-life easer</a>.</p>
<p><code>%p</code> tells <code>NSLog</code> to print the address of a pointer.</p>
<p><code>-className</code> returns gives the name of a class as an <code>NSString</code>.</p>
<p><em>Don&#8217;t manually print out a Cocoa <code>struct</code>, ever</em>, there are already <code>NSStringTo*</code> functions to do that for you, like <code>NSStringFromPoint()</code>.</p>
<p><code>NSStringFromSelector()</code> works as advertized (and paired with <code>NSSelectorFromString()</code> is very useful in general).</p>
<p><code>%lld</code> tells <code>NSLog</code> to print a <code>long long</code> (64-bit integer).  See also, <a href="http://www.cplusplus.com/reference/clibrary/cstdio/printf.html"><code>printf</code> reference</a>.</p>
<p><code>%Lf</code> tells <code>NSLog</code> to print a <code>long double</code>. See also, <a href="http://www.cplusplus.com/reference/clibrary/cstdio/printf.html"><code>printf</code> reference</a>.</p>
<p><strong>Best Practices</strong></p>
<p>Whenever you make a new object, I <em>strongly</em> recommended immediately implementing a <code>description</code> method, and religiously keeping it up to date (it&#8217;s not hard, honest!).  This won&#8217;t fix bugs, but it will make finding some of them <em>much easier</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/09/16/description-little-known-hero-of-debugging/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simplified Logging</title>
		<link>http://vgable.com/blog/2008/08/05/simpler-logging-2/</link>
		<comments>http://vgable.com/blog/2008/08/05/simpler-logging-2/#comments</comments>
		<pubDate>Wed, 06 Aug 2008 04:44:37 +0000</pubDate>
		<dc:creator>Vincent Gable</dc:creator>
				<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[Objective-C]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Sample Code]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Usability]]></category>
		<category><![CDATA[Debugging]]></category>
		<category><![CDATA[macros]]></category>
		<category><![CDATA[NSLog]]></category>

		<guid isPermaLink="false">http://vgable.com/blog/2008/08/05/simpler-logging-2/</guid>
		<description><![CDATA[I have noticed a pattern in my Cocoa code, which I have been able to simplify. I often print out the value of a variable for debugging. 99 times out of 100, the code looks like this: NSLog(@"actionURL = %@", actionURL);, where actionURL is some variable. But using the macros, I can say LOG_ID(actionURL);. This [...]]]></description>
			<content:encoded><![CDATA[<p>I have noticed a pattern in my Cocoa code, which I have been able to simplify.  I often print out the value of a variable for debugging.  99 times out of 100, the code looks like this: <code>NSLog(@"actionURL = %@", actionURL);</code>, where <code>actionURL</code> is some variable.</p>
<p>But using the macros, I can say <b><code>LOG_ID(actionURL);</code></b>.  This is <em>shorter</em>, and <em>non-repetitive</em>.</p>
<p><strong>The macros I use to simplify debugging (2008-09-16):</strong><br />
<code><br />
#define FourCharCode2NSString(err)	NSFileTypeForHFSTypeCode(err)</p>
<p>#define LOG_4CC(x)		NSLog(@"%s = %@", # x, FourCharCode2NSString(x))<br />
#define LOG_FUNCTION()	NSLog(@"%s", __FUNCTION__)<br />
#define LOG_ID(o)		NSLog(@"%s = %@", # o, o)<br />
#define LOG_INT(i)		NSLog(@"%s = %d", # i, i)<br />
#define LOG_INT64(ll)   NSLog(@"%s = %lld", # ll, ll)<br />
#define LOG_FLOAT(f)	NSLog(@"%s = %f", # f, f)<br />
#define LOG_LONG_FLOAT(f) NSLog(@"%s = %Lf", # f, f)<br />
#define LOG_OBJECT(o)	LOG_ID(o)<br />
#define LOG_POINT(p)	NSLog(@"%s = %@", # p, NSStringFromPoint(p))<br />
#define LOG_RECT(r)		NSLog(@"%s = %@", # r, NSStringFromRect(r))<br />
#define LOG_SIZE(s)		NSLog(@"%s = %@", # s, NSStringFromSize(s))</code></p>
<p>Look in <code>assert.h</code> for insight on how to roll your own debugging macros.</p>
]]></content:encoded>
			<wfw:commentRss>http://vgable.com/blog/2008/08/05/simpler-logging-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

