<?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>Evan Teran's Blog</title>
	<atom:link href="http://blog.codef00.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.codef00.com</link>
	<description>Just some thoughts from a computer geek</description>
	<lastBuildDate>Thu, 15 Dec 2011 20:14:34 +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>(Not so much) Fun with QSharedPointer</title>
		<link>http://blog.codef00.com/2011/12/15/not-so-much-fun-with-qsharedpointer/</link>
		<comments>http://blog.codef00.com/2011/12/15/not-so-much-fun-with-qsharedpointer/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 20:04:22 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=174</guid>
		<description><![CDATA[Qt has a wonderful way of dealing with memory management. The core idea is simple. Most objects have a parent, and when the parent gets destroyed, it will first destroy all it&#8217;s children. Using this technique, you can often write &#8230; <a href="http://blog.codef00.com/2011/12/15/not-so-much-fun-with-qsharedpointer/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Qt has a wonderful way of dealing with memory management. The core idea is simple. Most objects have a parent, and when the parent gets destroyed, it will first destroy all it&#8217;s children. Using this technique, you can often write your Qt applications with little to no concern for memory management. Often, you literally don&#8217;t have to have a single <code class="language-cpp">delete</code> in your entire application. That&#8217;s pretty sweet!</p>
<p>In addition, since Qt 4.5 <code class="language-cpp">QSharedPointer</code> was introduced, which is very similar in concept to <code class="language-cpp">boost::shared_ptr</code> (and thus <code class="language-cpp">std::tr1::shared_ptr</code>). I have long been a huge fan of the idea of smart pointers. They solve the need to worry about memory management for almost all usual cases. Unfortunately, when you combine these two concepts, sometimes you can go awry. I was surprised by this one, so I figured I&#8217;d shared my findings <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .<br />
<span id="more-174"></span></p>
<p>First we need some basic code to demonstrate the issue&#8230; Let&#8217;s suppose we have two trivial classes which inherit from <code class="language-cpp">QObject</code> and thus participate in the Qt style memory management system. They might look like this:</p>
<p>Parent.h</p>
<pre class="brush: cpp">class Parent : public QObject {
	Q_OBJECT
public:
	Parent(QObject *parent = 0) : QObject(parent) {
		std::cout << "Parent()" << std::endl;
	}

	virtual ~Parent() {
		std::cout << "~Parent()" << std::endl;
	}
};
</pre>
<p>Child.h</p>
<pre class="brush: cpp">class Child : public QObject {
	Q_OBJECT
public:
	Child(QObject *parent = 0) : QObject(parent) {
		std::cout << "Child()" << std::endl;
	}

	virtual ~Child() {
		std::cout << "~Child()" << std::endl;
	}
};
</pre>
<p>And finally, we have some code to make use of our wonder code above:</p>
<pre class="brush: cpp">void MyAwesomeFunction(Child *o) {
	std::cout << "Using Object!" << std::endl;
}

int main() {
	Parent *const parent = new Parent(0);
	Child *const child = new Child(parent);
	MyAwesomeFunction(child);
	delete parent;
}
</pre>
<p>The output of this simple program should be as follows:</p>
<pre>
Parent()
Child()
Using Object!
~Parent()
~Child()
</pre>
<p>As you can see, despite only explicitly deleting the <code class="language-cpp">parent</code>, the <code class="language-cpp">child</code> object gets cleaned up as well! This is great, heck if we made <code class="language-cpp">parent</code> an automatic object, we wouldn't even need to explicitly <code class="language-cpp">delete</code> it either. But what if <code class="language-cpp">MyAwesomeFunction</code> for whatever reason, took a <code class="language-cpp">QSharedPointer</code> instead of a raw pointer? You may just assume that you could write your code to be like this:</p>
<pre class="brush: cpp">void MyAwesomeFunction(const QSharedPointer<Child> &#038;o) {
	std::cout << "Using Object!" << std::endl;
}

int main() {
	Parent *const parent = new Parent(0);
	QSharedPointer<Child> child(new Child(parent));
	MyAwesomeFunction(child);
	delete parent;
}
</pre>
<p>well, if you made that assumption like I did, <strong>you'd be wrong</strong>! At best, this code leads to output like this:</p>
<pre>
Parent()
Child()
Using Object!
~Parent()
~Child()
QObject: shared QObject was deleted directly. The program is malformed and may crash.
</pre>
<p>At worst, it will crash. The question is, <strong>why is this broken?</strong> It all boils down to reference counting and who is doing the counting. What we have here, is <strong>two separate  reference counts</strong> on the same object. One maintained by the <code class="language-cpp">parent</code> object, one maintained by the <code class="language-cpp">QSharedPointer</code>, and they will certainly disagree on when to <code class="language-cpp">delete</code> the object. Leading to double free and use after free errors. <strong>No Bueno</strong>.</p>
<p>But it gets more complex than that! Qt memory management tries its best to let you do manual memory management while still maintaining it's own system. So if you <code class="language-cpp">delete</code> child before the parent is deleted, that's just fine. The child's destructor will deregister itself from its parent's child list. So the following is well formed:</p>
<pre class="brush: cpp">void MyAwesomeFunction(Child *o) {
	std::cout << "Using Object!" << std::endl;
}

int main() {
	Parent *const parent = new Parent(0);
	Child *const child = new Child(parent);
	MyAwesomeFunction(child);
	delete child;
	delete parent;
}
</pre>
<p>But if the parent happens to be delete'd first, then all hell breaks loose:</p>
<pre class="brush: cpp">void MyAwesomeFunction(Child *o) {
	std::cout << "Using Object!" << std::endl;
}

int main() {
	Parent *const parent = new Parent(0);
	Child *const child = new Child(parent);
	MyAwesomeFunction(child);
	delete parent;
	delete child;
}
</pre>
<p><strong>Segmentation fault</strong></p>
<p>When we use <code class="language-cpp">QSharedPointer</code>, this is essentially what we are doing if the object has a parent! The scary thing is, if the parent outlives the <code class="language-cpp">QSharedPointer</code> on average, then the bug doesn't show up (since then it will act like case #1). Fortunately, starting with Qt 4.8, if you attempt to write this type of broken code, you will see an assert like this:</p>
<pre>QSharedPointer: pointer 0x2384d70 already has reference counting</pre>
<p>Which at the very least gives us a basic idea that there is something wrong, and it involves a <code class="language-cpp">QSharedPointer</code>. It's a start.</p>
<p>The simplest approach to the problem is to simply not mix and match the two memory management schemes. If you need a <code class="language-cpp">QSharedPointer</code>, <strong>don't set the parent</strong>. Like this:</p>
<pre class="brush: cpp">void MyAwesomeFunction(const QSharedPointer<Child> &#038;o) {
	std::cout << "Using Object!" << std::endl;
}

int main() {
	Parent *const parent = new Parent(0);
	QSharedPointer<Child> child(new Child());
	MyAwesomeFunction(child);
	delete parent;
}
</pre>
<p>which will happily output the following:</p>
<pre>
Parent()
Child()
Using Object!
~Parent()
~Child()
</pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2011/12/15/not-so-much-fun-with-qsharedpointer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Combining Qt&#8217;s Signals and Slots with c++0x lamdas</title>
		<link>http://blog.codef00.com/2011/03/27/combining-qts-signals-and-slots-with-c0x-lamdas/</link>
		<comments>http://blog.codef00.com/2011/03/27/combining-qts-signals-and-slots-with-c0x-lamdas/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 03:26:52 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[c++0x]]></category>
		<category><![CDATA[lambda]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=155</guid>
		<description><![CDATA[Qt is a fantastically designed library. However, every now and then I think of something that I wish they offered that they don&#8217;t. It&#8217;s almost always something small and easily worked around, but it would be nice if it were &#8230; <a href="http://blog.codef00.com/2011/03/27/combining-qts-signals-and-slots-with-c0x-lamdas/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Qt is a fantastically designed library. However, every now and then I think of something that I wish they offered that they don&#8217;t. It&#8217;s almost always something small and easily worked around, but it would be nice if it were just there. This time around, that feature is the ability to connect a signal to a function which is not a member of a class/struct. Specifically, I think it would be really cool if I could connect it to a c++0x lambda! Especially now that the <a href="http://herbsutter.com/2011/03/25/we-have-fdis-trip-report-march-2011-c-standards-meeting/">ISO C++ committee approved the  C++0x final draft</a>.</p>
<p><span id="more-155"></span><br />
Fortunately, this turned out to be a fairly easy. Firstly we need an object to receive the signal since Qt mandates that all slots are member functions. Seems easy enough, so we&#8217;ll start with that:</p>
<pre class="brush: cpp">class connect_functor_helper : public QObject {
    Q_OBJECT
public:
    // TBD
};
</pre>
<p>And we of course need a function to do the connection, we&#8217;ll template it so it can accept anything, a function, a functor, or even a lambda <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<pre class="brush: cpp">template &lt;class T&gt;
bool connect(QObject *sender, const char *signal, const T &#038;reciever, Qt::ConnectionType type = Qt::AutoConnection) {
    // TBD
}
</pre>
<p>The pieces are all here, all we have to do is put them together. I do wish that MOC supported templated types, that would make this slightly easier (since we want to allow anything to be connected to). So I ended up resorting to using <code class="language-cpp">boost::function</code>. When we fill in the blanks, the class looks like this:</p>
<pre class="brush: cpp">class connect_functor_helper : public QObject {
	Q_OBJECT
public:
	connect_functor_helper(QObject *parent, const boost::function&lt;void()&gt; &#038;f) : QObject(parent), function_(f) {
	}

public Q_SLOTS:
	void signaled() {
		function_();
	}

private:
	boost::function&lt;void()&gt; function_;
};
</pre>
<p>So two things are happening here that&#8217;s noteworthy.</p>
<ul>
<li>We make the helper object a child of the some QObject (ideally the sender of the signal), so that it will be automatically deleted when the parent object gets destroyed.</li>
<li>We have a simple <code class="language-cpp">boost::function</code> to store the function we want and call it from a slot called <code class="language-cpp">signaled()</code>. We use this because it allows us to be generic without resorting to templates.</li>
</ul>
<p>The last thing is to just add the connection, which is easy enough <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> .</p>
<pre class="brush: cpp">template &lt;class T&gt;
bool connect(QObject *sender, const char *signal, const T &#038;reciever, Qt::ConnectionType type = Qt::AutoConnection) {
	return QObject::connect(sender, signal, new connect_functor_helper(sender, reciever), SLOT(signaled()), type);
}
</pre>
<p>Huzzah! We now can connect a Qt signal to anything that is callable like a function with the prototype <code class="language-cpp">void f()</code>, even lambdas! Of course this can be expanded to deal with parameters as well, this is just the tip of the iceberg. So once we put all of the above into a header, we finally have the following demonstration program which works when <code class="language-cpp">QMAKE_CXXFLAGS</code> contains <code class="language-cpp">--std=c++0x</code>:</p>
<pre class="brush: cpp">
#include &lt;QApplication&gt;
#include &lt;QPushButton&gt;
#include &lt;iostream&gt;
#include "LambdaConnect.h"

int main(int argc, char *argv[]) {
	QApplication app(argc, argv);
	QPushButton w("Push Me");
	w.show();
	connect(&#038;w, SIGNAL(clicked()), []{
		std::cout << "clicked" << std::endl;
	});
	app.exec();
}
</pre>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2011/03/27/combining-qts-signals-and-slots-with-c0x-lamdas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>GMP error handling frustrates me</title>
		<link>http://blog.codef00.com/2011/03/21/gmp-error-handling-frustrates-me/</link>
		<comments>http://blog.codef00.com/2011/03/21/gmp-error-handling-frustrates-me/#comments</comments>
		<pubDate>Mon, 21 Mar 2011 16:23:32 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=147</guid>
		<description><![CDATA[The GNU Multiple Precision Arithmetic Library (GMP) is a wonderful library. It offers arbitrary precision math in a relatively simple, easy to use package. It is currently used in kcalc as the core for all basic math operations. The only problem is, &#8230; <a href="http://blog.codef00.com/2011/03/21/gmp-error-handling-frustrates-me/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a class="vt-p" href="http://gmplib.org/">The GNU Multiple Precision Arithmetic Library</a> (GMP) is a wonderful library. It offers arbitrary precision math in a relatively simple, easy to use package. It is currently used in <a class="vt-p" href="http://utils.kde.org/projects/kcalc/">kcalc</a> as the core for all basic math operations. The only problem is, the error handling it offers, is broken by design.</p>
<p><span id="more-147"></span></p>
<p>What could possibly be so broken in such a useful library? <code class="language-cpp">abort()</code>. That&#8217;s right, this simple C library function is the thorn in my side that makes using GMP annoying. So what&#8217;s so bad about this function?</p>
<p>Here&#8217;s the problem, when allowing the user to enter arbitrary values to calculate with (like kcalc), it is trivial to create numbers that are so big, that it would take more RAM than you have to represent it in memory. For example: 549,755,813,888!, that&#8217;s right, the factorial of that number. As you can imagine, that is a ridiculously large number. So big in fact that GMP gives up before it even starts.</p>
<p>It&#8217;s actually good that GMP gives up before wasting the user&#8217;s time, the problem is <strong>how</strong> it gives up. It does so by printing a message to <code class="language-cpp">stderr</code> and calling <code class="language-cpp">abort()</code>. Keep in mind, this is a <strong>library</strong>, not an application. This means that is is simply part of another application which could be doing anything. Yet when GMP fails, it gives the the application, (you know that thing that the user cares about) absolutely no easy opportunity to deal with the issue. All the user sees is a crash.</p>
<p>This is what I&#8217;ve had to resort to in order to work around this:</p>
<pre class="brush: cpp">static jmp_buf abort_factorial;
static void factorial_abort_handler(int)
{
    longjmp(abort_factorial, 1);
}

detail::knumber *detail::knuminteger::factorial() const
{
	// ----snip----
	// some basic sanity checking here ...
	// ----snip----

    struct sigaction new_sa;
    struct sigaction old_sa;

    sigemptyset(&amp;new_sa.sa_mask);
    new_sa.sa_handler = factorial_abort_handler;
    sigaction(SIGABRT, &amp;new_sa, &amp;old_sa);

    if(setjmp(abort_factorial)) {
        sigaction(SIGABRT, &amp;old_sa, 0);
        return new knumerror(UndefinedNumber);
    }

	// ----snip----
	// attempt to do interesting work here ...
	// ----snip----

    sigaction(SIGABRT, &amp;old_sa, 0);

    return tmp_num;
}</pre>
<p>I have to resort to setting up a signal handler before doing the work and using <code class="language-cpp">longjmp()</code> to clean up the mess neatly if an abort happens. I can&#8217;t even use c++ exceptions to handle this because <code class="language-cpp">SIGABRT</code> isn&#8217;t trapped by them. I suppose I could do something &#8220;clever&#8221; and replace the libc&#8217;s <code class="language-cpp">abort()</code> function with my own, but that&#8217;s just another hack, I want a clean approach.</p>
<p>Fortunately, I don&#8217;t just bring problems, I also bring solutions <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> . What GMP should do is offer a &#8220;fatal error&#8221; handler. Something like this would be great:</p>
<p><code class="language-cpp">void gmp_fatal(const char *reason) { (*gmp_fatal_ptr)(reason); }</code> where <code class="language-cpp">gmp_fatal_ptr</code> is a function pointer that can be set by the application. </p>
<p>Heck by default, it can point to a function which prints the reason to <code class="language-cpp">stderr</code> and calls <code class="language-cpp">abort</code>, this would mean that most users and application writers wouldn&#8217;t even see the difference. But at least give me the option to deal with it in a reasonable fashion that isn&#8217;t a crash.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2011/03/21/gmp-error-handling-frustrates-me/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>HTML5 and undefined tags</title>
		<link>http://blog.codef00.com/2011/03/08/html5-and-undefined-tags/</link>
		<comments>http://blog.codef00.com/2011/03/08/html5-and-undefined-tags/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 21:38:47 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[html5]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=104</guid>
		<description><![CDATA[So I was just reading up on the upcoming HTML5 standard and am generally very pleased with the work they&#8217;ve done. But a though occurred to me, since HTML5 is effectivly going &#8220;version-less&#8220;, web designers are going to have to &#8230; <a href="http://blog.codef00.com/2011/03/08/html5-and-undefined-tags/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I was just reading up on the upcoming <a href="http://www.whatwg.org/specs/web-apps/current-work/">HTML5 standard</a> and am generally very pleased with the work they&#8217;ve done. But a though occurred to me, since HTML5 is effectivly going &#8220;<a href="http://blog.whatwg.org/html-is-the-new-html5">version-less</a>&#8220;, web designers are going to have to use javascript in order to detect features client side and either inject elements into the DOM when they are there, or inject some fallback code if they are not. There has been a lot of nice work on this front, specifically <a href="http://diveintohtml5.org/detect.html">modernizr</a> is a very cool library for this. But maybe there is a cleaner, better way.</p>
<p><span id="more-104"></span></p>
<p>First let me be clear, that why I am about to suggest is not currently valid HTML, it is what I think HTML5 should be, not what it is. So please don&#8217;t get upset if you try this and it doesn&#8217;t work.</p>
<p>So I want my idea to be simple and <strong>not require</strong> javascript. Using javascript to detect features is nice and all, but I don&#8217;t want to depend on this. I would like to be able to just write my html, and have it gracefully fallback if the feature is not there. This sounds complicated, but I believe that it isn&#8217;t.</p>
<p>A simple rule could be introduced to aid in this effort. While I&#8217;m sure there are corner cases that I am not considering, I think something like this would be good enough for:</p>
<blockquote><p>If a unknown tag is encountered, treat it as a &lt;div&gt;. If the unknown tag is self closing, then treat as if it had a closing. When treating an unknown tag as a &lt;div&gt;, ignore attributes not applicable to a &lt;div&gt;. If a tag introduced in HTML5 is encountered and understood, then simply ignore any inner HTML that doesn&#8217;t apply.</p></blockquote>
<p> This would allow us to write something like the following:</p>
<pre><code style="language-html">
&lt;video width="320" height="240" controls&gt;
  &lt;source src="pr6.mp4"  type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'&gt;
  &lt;source src="pr6.webm" type='video/webm; codecs="vp8, vorbis"'&gt;
  &lt;source src="pr6.ogv"  type='video/ogg; codecs="theora, vorbis"'&gt;
  &lt;span style="color:red"&gt;Sorry, but your browser doesn't appear to support HTML5 video....&lt;/span&gt;
&lt;/video&gt;
</code></pre>
<p>So, how would this be parsed using the rules I&#8217;ve supplied? Suppose the browser doesn&#8217;t implement the &lt;video&gt; tag, well then it would be parsed like this:</p>
<pre><code style="language-html">
&lt;div&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;div&gt;&lt;/div&gt;
  &lt;span style="color:red"&gt;Sorry, but your browser doesn't appear to support HTML5 video....&lt;/span&gt;
&lt;/div&gt;
</code></pre>
<p>So we have a bunch of &lt;div&gt; tags. We could use CSS to make it have the same dimmensions as the video would have if we like (making it still fit nicely in the design), and we have some fallback code there. Heck, the fallback code could a &lt;script&gt; tag, or perhaps even an &lt;embed&gt; tag which falls back onto flash content. This makes the options pretty much ideal.</p>
<p>So using this rule, how is that first block parsed if the browser does support the &lt;video&gt; tag? Well it&#8217;s pretty simple, it just acts like the &lt;span&gt; isn&#8217;t there since it isn&#8217;t applicable to a &lt;video&gt; tag. It ends up looking like this:</p>
<pre><code style="language-html">
&lt;video width="320" height="240" controls&gt;
  &lt;source src="pr6.mp4"  type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'&gt;
  &lt;source src="pr6.webm" type='video/webm; codecs="vp8, vorbis"'&gt;
  &lt;source src="pr6.ogv"  type='video/ogg; codecs="theora, vorbis"'&gt;
&lt;/video&gt;
</code></pre>
<p>I&#8217;m not aware of any tags introduced by HTML which are outright incompatible with this concept. Many of the new tags are really just containers which have new semantic value. If treated like a &lt;div&gt;, we can use CSS to at least make them look the part.</p>
<p>To a certain degree this is already being done, the HTML5 standard says:</p>
<blockquote><p>Content may be provided inside the video element. User agents should not show this content to the user; it is intended for older Web browsers which do not support video, so that legacy video plugins can be tried, or to show text to the users of these older browsers informing them of how to access the video contents.</p></blockquote>
<p>And applies the same rule to the &lt;audio&gt; tag. But this is specific to just &lt;video&gt; and &lt;audio&gt; tags, and doesn&#8217;t really spell out how arbitrary tags should be handled as far as I can tell. Can I put an script in there and expect it to work on older browsers? I don&#8217;t know because it just doesn&#8217;t say. But it&#8217;s a good start.</p>
<p>The result? We have plain HTML which will attempt to use the new feature first, and without depending on javascript, will gracefully fallback and display alternate content. Seems like an ideal solution to me. Not only that, but it would be <strong>easy</strong> to implement this in older browsers. The fact of the matter is, I didn&#8217;t see in the HTML5 specs exactly what the user agent is supposed to do when it encounters an undefined tag. It&#8217;s a big document, and perhaps I overlooked it, that&#8217;s certainly possible. But if it isn&#8217;t defined, then I think that is an oversight with regard to consistent behavior.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2011/03/08/html5-and-undefined-tags/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Default Browser on Linux Debacle</title>
		<link>http://blog.codef00.com/2011/02/18/the-default-browser-on-linux-debacle/</link>
		<comments>http://blog.codef00.com/2011/02/18/the-default-browser-on-linux-debacle/#comments</comments>
		<pubDate>Fri, 18 Feb 2011 19:41:43 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=84</guid>
		<description><![CDATA[The concept of a default browser on linux is a complete mess. There doesn&#8217;t seem to be any central, agreed upon method of defining what the default browser is. First there is the $BROWSER environment variable. This seems like a &#8230; <a href="http://blog.codef00.com/2011/02/18/the-default-browser-on-linux-debacle/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>The concept of a default browser on linux is a complete mess. There doesn&#8217;t seem to be any central, agreed upon method of defining what the default browser is. First there is the <code>$BROWSER</code> environment variable. This seems like a good idea, it can be set globally, and on a per user basis. On the command line, all you need to do is type <code>$BROWSER http://...</code> and you on your way to the website of your choice. If only it were that easy&#8230;<br />
<span id="more-84"></span><br />
Unfortunately, this isn&#8217;t widely adopted. In fact on my Gentoo system it doesn&#8217;t seem to have any real effect at all. I set in my <code>~/.bashrc</code>, <code>export BROWSER=/usr/bin/chromium</code>, and yet in the chromium preferences, it still complains that it isn&#8217;t the default browser. I know, it would probably be more seamless if I used another distro, but I feel the upstream maintainers of the applications need to agree on a default browser concept, which would make the choice of distro irrelevant.</p>
<p>So on to choice B, I use KDE so I look in the KDE system-settings. In the &#8220;Default Applications&#8221; section, there is an options for web browser, looks promising. Once again, foiled by the fact that the setting is not universally used. The value chosen is stored in <code>~/.kde4/share/config/kdeglobals</code> and only respected by KDE/Qt applications. This does most of the job, but I like most users don&#8217;t exclusively use just KDE applications, I choose my applications based on how useful they are, not which widget set they are built with. So pretty much all the Gtk/Gnome/other applications still don&#8217;t respect the setting. For example, links in thunderbird always want to open with firefox. I even tried creating a user.js file in my thunderbird profile directory and setting <code>network.protocol-handler.app.http</code> to my choice of browser, no joy. In the &#8220;about:config&#8221; the settings are there, the application just didn&#8217;t seem to care. I am sure I did something wrong, but even if I did, it shouldn&#8217;t be so hard. There should be a dirt simple way to set the default browser for <strong>all</strong> applications for my user and then, if they like, applications can provide some mechanism to override this.</p>
<p>I am sure that Gnome as there own way of setting the default browser, and I think it is likely that it works great for Gnome applications and KDE/Qt applications probably ignore it.</p>
<p>The Debian folks have a nice idea, they leverage the &#8220;alternatives&#8221; mechanism to provide &#8220;x-www-browser&#8221; which is (I think) in the end a symlink to the browser of your choice. This is great <strong>if</strong> everyone agrees to launch the browser with this, but has a minor downside. It only addresses system level preferences, not user level. So while you can hypothetically set the default browser system wide (probably good enough considering how many users are the only user of their systems), if an individual user wants to override this, I&#8217;m not sure there is an elegant way to do this. &#8220;x-www-browser&#8221; just ends up being a less flexible variation of the $BROWSER environment variable.</p>
<p>Also, I&#8217;ve looked into xdg-settings, looks promising, from freedesktop.org which a lot of people have been working on standardizing with. Let see what happens when I play with it.</p>
<p><code><br />
$ xdg-settings --list<br />
Known properties:<br />
  default-web-browser           Default web browser<br />
</code></p>
<p>Ohh, looking good! </p>
<p><code><br />
$ xdg-settings get default-web-browser<br />
which: no chromium in (/usr/bin/chromium<br />
!/usr/bin)<br />
 in (/usr/bin)l-workbench<br />
MySQLWorkbench.desktop<br />
</code></p>
<p>Crap, what the heck does that mean? Why is &#8220;MySQLWorkbench.desktop&#8221; mentioned? <strong>What is going on?</strong> Ok, I&#8217;m done with my little panic, I&#8217;ll try to fix it:</p>
<p><code><br />
$ xdg-settings set default-web-browser /usr/bin/chromium<br />
xdg-settings: invalid application name<br />
Try 'xdg-settings --help' for more information.<br />
</code></p>
<p>OK, usage, not as obvious as I thought&#8230;</p>
<p><code><br />
$ xdg-settings --help<br />
xdg-settings - get various settings from the desktop environment</p>
<p>Synopsis</p>
<p>xdg-settings { get | check | set } {property} [value]</p>
<p>xdg-settings { --help | --list | --manual | --version }</p>
<p>Use 'man xdg-settings' or 'xdg-settings --manual' for additional info.<br />
</code></p>
<p>Help&#8230; not so helpful. Aha, I figured it out from looking at the manual!</p>
<p><code>$ xdg-settings set default-web-browser chromium-chromium.desktop</code></p>
<p>Did it work?</p>
<p><code><br />
$ xdg-settings get default-web-browser<br />
which: no chromium in (/usr/bin/chromium<br />
!/usr/bin)<br />
 in (/usr/bin)l-workbench<br />
MySQLWorkbench.desktop<br />
</code></p>
<p><strong>Crap!</strong></p>
<p>Alright, xdg-settings while I nice concept, simply isn&#8217;t working. So disappointing.</p>
<p>So I&#8217;ve got a lot of options, <strong>none of which are 100% effective</strong>.</p>
<p>So what&#8217;s the ideal solution? It&#8217;s hard to say, probably a hybrid of some of these ideas. I think a single binary/script named <code>/usr/bin/www-browser</code> which would look first in user&#8217;s home directory for a setting and if not found, look /etc/ for a global setting. And would launch the browser of choice. Why not just get everyone to agree on $BROWSER? Well, unfortunately the different browsers have different command line switches. Have a script/binary gives us the opportunity to normalize how the common ones are accessed (if any). More generally, it would allow the config file to have more advanced options than just specifying the path of the default browser.  xdg-settings does look like it is on the right track, but I honestly couldn&#8217;t get it to do anything that made sense.</p>
<p>Most importantly the application writers (I&#8217;m looking at you KDE and Gnome) need to agree upon whatever method they think is best. I honestly don&#8217;t care too much about how it works, as long as it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2011/02/18/the-default-browser-on-linux-debacle/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How not to handle a bug report</title>
		<link>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/</link>
		<comments>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 04:43:47 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=63</guid>
		<description><![CDATA[I recently submitted a bug report to Qt software, the results were less than impressive. One thing I&#8217;d like to make clear though is that Qt is an amazing library that I would recommend to any c++ software developer, I &#8230; <a href="http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I recently submitted a bug report to <a class="vt-p" href="http://qt.nokia.com/" target="_blank">Qt software</a>, the results were less than impressive. One thing I&#8217;d like to make clear though is that Qt is an amazing library that I would recommend to any c++ software developer, I truly mean that. It is well designed, well documented and generally works as advertised. On top of all of this, it is portable! It really just gets better and better. Which is why I found the handling of my bug report so&#8230; underwhelming.</p>
<p><span id="more-63"></span>It all started with a compiler warning. I like to compile my gcc projects with:</p>
<pre><code>-ansi -pedantic -W -Wall</code></pre>
<p>and I like my projects to compile with <strong>no warnings</strong>. My personal feelings on this subject are that if you cannot find a way to reconcile the warning, then odds are you don&#8217;t understand what it is trying to warn you about. Anyway, on to the issue at hand. I added a macro call of <a class="vt-p" href="http://doc.trolltech.com/4.6/qtglobal.html#QT_REQUIRE_VERSION" target="_self">QT_REQUIRE_VERSION</a> to the main function in one of my projects, the goal of course is to give a run-time error if the program is run with a version of Qt that is too old, simple enough. Unfortunately, this caused a warning in my project which I found entirely unacceptable.</p>
<pre><code>main.cpp: In function 'int main(int, char**)':
main.cpp:8: warning: format not a string literal and no format arguments</code></pre>
<p>I&#8217;m sure that many of you can relate to the horror I felt after seeing this in my usually clean build. First I checked, then double checked that the usage of the macro was the cause. Yup, commenting out the simple one liner use of the macro made it go away. Did I use it right? well  the call basically looks like this:</p>
<pre><code class="language-cpp">QT_REQUIRE_VERSION(argc, argv, "4.0.2")</code></pre>
<p>Not much room for error there, and the only string parameter is passing a string literal. So what&#8217;s going on here? I figured it&#8217;s a pretty minor issue so I&#8217;d be patient. After waiting a while for someone to notice this, I finally decided to <a class="vt-p" href="http://bugreports.qt.nokia.com/browse/QTBUG-8547" target="_self">submit a bug</a>. Two or so weeks went by then I finally saw that my bug had be resolved as &#8220;invalid&#8221;. Fine, my gut reaction was to check if I had misused the macro, so I&#8217;ll check out what they had to say.</p>
<blockquote><p>I believe the warning is due to there being no semicolon after the call  to QT_REQUIRE_VERSION.  Note that the warning message specifies line 8 –  the line after the QT_REQUIRE_VERSION call.  The QT_REQUIRE_VERSION  macro, like most macros, does not end with a semi-colon, so you have to  use one after calling it.</p></blockquote>
<p>I was thrilled that it was such a simple fix. How could I have been so dumb as to miss a semi-colon. An amateur mistake! So I thanked the bug assignee, mentioned that the docs didn&#8217;t have a semicolon and went on my way. Of course this wouldn&#8217;t be much of a post if things were that simple&#8230;</p>
<p>As you may have guessed the proposed solution had nearly zero effect on the presence of the warning. I have to say &#8220;nearly&#8221; there because it did change the line number it occurred on to be the line of the macro, instead of the line after. But the warning still remains, mocking me.</p>
<p>Let&#8217;s revisit the response I got (i&#8217;m adding emphasis).</p>
<blockquote><p>I <strong>believe</strong> the warning is due to there being no semicolon after the call   to QT_REQUIRE_VERSION&#8230;</p></blockquote>
<p>Ahh, I see, so he just guessed! I think it&#8217;s time for a basic rule of bug handling to be established.</p>
<p><strong>1.</strong> Actually test the bug and then test the solution before any resolution is given!</p>
<p>This may sound simple, but clearly it didn&#8217;t happen here. He did not test the issue or its solution, he simply looked at my example code and made a wild guess. It would have taken him all of 1 minute to copy and paste my code into a test.cpp file and compile it with the flags I gave to see that the warning would remain.</p>
<p>I looked for way to re-open the bug, but could not, so I <a class="vt-p" href="http://bugreports.qt.nokia.com/browse/QTBUG-8967" target="_self">submitted a second one</a>. This time I made it clear that this was a followup to the other bug report and that I had added the semicolon, which did not help. If you are wondering how clear I was, here&#8217;s a quote from my bug report:</p>
<blockquote><p><strong>Note: I&#8217;ve added a semicolon as recommended by the previous bugs  resolution.</strong> Which did change the warning&#8217;s line number to 7 from 8.  But the warning still stands.</p></blockquote>
<p>Later that day I saw on my phone an email from the Qt bug tracker saying the status had changed. Less than 24 hours, that&#8217;s great turn around time, maybe I was in luck. Nope, not this time, the same assignee still didn&#8217;t do a good job <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> . He assigned it to someone in documentation with the following comment (remember my bug report was about a compile time warning, the documentation was a side issue).</p>
<blockquote><p>The problem was a missing semi-colon after the macro call, but that what  the doc example leads you to do.</p>
<p>The example in the docs should be updated to have a semi-colon after  the macro call, otherwise following the example produces code that fails  to compile and the compiler error message is not very helpful.</p></blockquote>
<p>Great! I&#8217;m glad we could get the documentation squared away, but how about fixing the actual bug I reported!</p>
<p><strong>2.</strong> Read the actual contents of the bug report. Don&#8217;t just glaze over it and assume you know what I meant. Read it.</p>
<p>I don&#8217;t think it is too much to ask that the assignee of the bug actually read the bug report before drawing conclusions. This was a complete disregard for the reported issue. At this point I was annoyed, so I decided to look into the issue myself. Here&#8217;s the macro in question:</p>
<pre><code class="language-cpp">#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
QString sq = QString::fromLatin1(qVersion()); \
if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()&lt;&lt;16)+\
(sq.section(QChar::fromLatin1('.'),1,1).toInt()&lt;&lt;8)+\
sq.section(QChar::fromLatin1('.'),2,2).toInt()&lt;(s.section(QChar::fromLatin1('.'),0,0).toInt()&lt;&lt;16)+\
(s.section(QChar::fromLatin1('.'),1,1).toInt()&lt;&lt;8)+\
s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
if (!qApp){ \
    new QApplication(argc,argv); \
} \
QString s = QApplication::tr("Executable '%1' requires Qt "\
 "%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal(s.toLatin1().data()); }}</code></pre>
<p>First thing to note is that the whole thing is wrapped in brackets, meaning that the semicolon isn&#8217;t strictly required and thus a complete non-issue. Sure there is the subtle issues involving things like this:</p>
<pre><code class="language-cpp">if (&lt;condition&gt;) MACRO(a); else foo(a);</code></pre>
<p>But this macro is meant to be used unconditionally as the first statement in the program, nothing major. Personally I&#8217;d recommend wrapping the macro in a
<pre><code class="language-cpp">do {/*...*/} while(0)</code></pre>
<p>, but that&#8217;s a different discussion. Anyway, did you catch the source of the warning? Took me a bit but the issue is the very last statement:</p>
<pre><code class="language-cpp">qFatal(s.toLatin1().data());</code></pre>
<p>Basically, they&#8217;ve constructed a QString, getting the equivalent c-string and passing that to qFatal, seems harmless enough. Let&#8217;s look at the definition for qFatal:</p>
<pre><code class="language-cpp">Q_CORE_EXPORT void qFatal(const char *, ...) /* print fatal message and exit */
#if defined(Q_CC_GNU) &amp;&amp; !defined(__INSURE__)
    __attribute__ ((format (printf, 1, 2)))
#endif
;</code></pre>
<p>Aha! qFatal is a printf style function, it even has the printf attribute when compiled with gcc. Which basically means we can expect that values passed will likely be given to something like vsprintf, followed by an abort call. This function is called qFatal after all. We all know that it is good security practice to always have the first parameter of a printf function be a string literal to prevent format string vulnerability (at least we all <strong>should</strong> know&#8230;), so the warning is well founded.</p>
<p>Out of curiousity, I tried something like this:</p>
<pre><code class="language-cpp">QT_REQUIRE_VERSION(argc, argv, "4.7.0%n%n%n%n");</code></pre>
<p>Boom! Segmentation fault (instead of the expected abort). That means that those %n&#8217;s are trampling memory, which is simply not good. Fortunately the odds of this macro being passed a value provided by a user is pretty much zero, so there is no practical vulnerability here, but it is still an issue, one which has a simple solution. If we simply change the last statment to look like this:</p>
<pre><code class="language-cpp">qFatal("%s", s.toLatin1().data());</code></pre>
<p>Then all of these issues go away. No warning, no format string crashes when you do naughty things, it just works correctly. I&#8217;ve added all of these details to my bug report, so far no response. I still love Trolltech and thank them for their wonderful product which I will continue to recommend to people and be a happy user of. But someone over there really just wasn&#8217;t doing their job well. Once I got frustrated enough to look, it took me all of 15 minutes to figure out exactly what was causing the warning and come up with a functional solution. Instead my report has been assigned to documentation where it will likely sit for days until someone realizes it doesn&#8217;t belong there. Wish me luck, I&#8217;ve got my fingers crossed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2010/03/13/how-not-to-handle-a-bug-report/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Flash accidentally subverts the privacy mode of newer browsers?</title>
		<link>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/</link>
		<comments>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 21:12:58 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[flash]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=58</guid>
		<description><![CDATA[Pretty much all of the popular browsers now support a &#8220;private browsing&#8221; mode. The whole concept of this mode is to prevent any history of your browsing activities from being recorded. The problem is that there is nothing forcing browser &#8230; <a href="http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Pretty much all of the popular browsers now support a &#8220;private browsing&#8221; mode. The whole concept of this mode is to prevent any history of your browsing activities from being recorded. The problem is that there is nothing forcing browser extensions to respect this mode of operation.</p>
<p><span id="more-58"></span>I&#8217;ve recently discovered that Flash player&#8217;s settings system stores settings for every site which references flash player. This is a nice usability feature. It allows your flash related settings to work across browser sessions, even different browsers as long as you remain in the same account. But, the filing system itself is also a history of all flash enabled sites you&#8217;ve visited.</p>
<p>On my Linux box, I have the following directory:</p>
<pre>~/.macromedia/Flash_Player/macromedia.com/support/flashplayer/sys</pre>
<p>I also found a similar directory on my windows 7 box, so this is not just a Linux phenomenon. In this directory is a bunch of directories whose names are things like &#8220;#mail.google.com&#8221; and &#8220;#viddler.com&#8221;, each of which has a settings.sol file containing the flash settings for that particular domain. These get created and updated <strong>regardless of privacy mode and any history clearing</strong> you ask your browser to do.</p>
<p>Fortunately, these files are safe to delete (they&#8217;ll just get recreated if needed). If you go to:<a href="http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html" target="_blank"> http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager.html</a>, there are settings there that allow you to manage the offline storage settings, but from my quick tests it seems that the folders are created even when you set the allowed storage to 0Kbs.</p>
<p>Obviously this doesn&#8217;t give a complete list of all sites that were visited, but lets face it, much of the questionable content on the internet is served by flash.</p>
<p>Yet another reason to use <a href="http://noscript.net/" target="_blank">noscript</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2010/02/16/flash-accidentally-subverts-the-privacy-mode-of-newer-browsers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How not to maintain an API</title>
		<link>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/</link>
		<comments>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 05:25:38 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[c++]]></category>
		<category><![CDATA[graphviz]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=51</guid>
		<description><![CDATA[So I&#8217;ve been working on my graphing code for EDB.  I was eventually able create a Qt widget which natively  renders a graphviz graph layout. It actually works quite nicely, you can create an ordinary graphviz graph either in memory &#8230; <a href="http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I&#8217;ve been working on my graphing code for <a class="vt-p" href="http://www.codef00.com/projects.php#debugger" target="_blank">EDB</a>.  I was eventually able create a <a class="vt-p" href="http://qt.nokia.com/" target="_blank">Qt</a> widget which natively  renders a <a class="vt-p" href="http://www.graphviz.org/" target="_blank">graphviz</a> graph layout. It actually works quite nicely, you can create an ordinary graphviz graph either in memory or from a file like usual.  The code can simply create a &#8220;GraphWidget&#8221; and the code will display the graph perfectly (there are some constructs which it doesn&#8217;t support, but the basics are there) with nice things such as zooming and rotating.</p>
<p>All of this works great, except for the fact that graphviz decided to change some of the structures used to represent the layed out graph.</p>
<p><span id="more-51"></span>The most annoying issue I found is that the older versions of the graphviz headers did not have any defines for versioning. This means that there is no good way to detect at compile time which version you are trying to compile against. Later one was introduced, which means that you can coarsely determine if you are compiling against a version before or after that macro was introduced. But this isn&#8217;t really good enough given than there have been several changes over time before and after this macro was introduced.</p>
<p><strong>So rule #1: If you plan to change anything in your publicly installed headers, ever, have a version macro which is unique for each and every version of structures and API.</strong></p>
<p>Of course, the fun doesn&#8217;t stop there, otherwise I wouldn&#8217;t have a whole lot to write about here. In addition to that, they decided to make the version macro they did create resolve to a string! This is great and all for displaying the version to the user. But is not easily comparable at compile time at all. The most creative solution I can think of is to have a configure script which will emit run a program  which includes the header and outputs the version if available, then finally the configure script will parse the result and produce a compile time comparable macro. This is some of what the autotools scripts do to produce things like config.h. But is less than fun to deal with.</p>
<p><strong>Rule #2: Make the version macro numeric, and encode things in a way that x &gt;= y always means that x is newer.</strong></p>
<p>Something like this feels ideal.<br />
<code class="language-cpp">#define VERSION 0x00010203 /* version 1.2.3 */</code><br />
Here I am suggesting to use a 32-bit constant for the version, dividing on byte boundaries for trivial decoding and ease of human readability.  There is no need to stick to the tradition versioning schemes either. Lately, I&#8217;ve been preferring using the year and release number like this:<br />
<code class="language-cpp">#define VERSION 0x00200901 /* version 2009.1 */</code><br />
Both work equally well. But wait there is more nonsense! The graphviz people decided to use macros to access the members of the primary structures (node, edge, graph). This way they can change the implementation details of these structures but the code using these structures can remain the same. <strong>This was a good idea</strong>. Unfortunately, they didn&#8217;t do it for all of the structures. Only those three. But there are a whole bunch of structures representing text labels, coordinates and other fun stuff which didn&#8217;t use this system.</p>
<p><strong>Rule #3: Be consistent with your API.</strong></p>
<p>Finally, they used to have both floating point and non floating point versions of certain data members. At some point they decided to switch to only floating point. The problem is that some things changed type, but not the name. So if I wanted to store the value of one of these, I can&#8217;t conveniently. For example:<br />
<code class="language-cpp">struct T { point *pos; };</code><br />
became<br />
<code class="language-cpp">struct T { pointf *pos; };</code><br />
This makes code such as this unfortunately broken across versions.<br />
<code class="language-cpp">point *p = x.pos;</code><br />
If I had a usable version macro, I could make the type depend on the version. Even worse some things changed names and types. For example:<br />
<code class="language-cpp">ND_coord_i /* returns "struct point " */</code><br />
was replaced by:<br />
<code class="language-cpp">ND_coord /* returns "struct pointf" */</code><br />
The former no longer exists. At least I can test for the existence of the ND_coord macros to figure out which to use, but the net result is messier code.</p>
<p><strong>Rule #4: Do everything possible to avoid changing datatypes of structure members and return types of functions. It makes storing the result ugly and convoluted.</strong></p>
<p>One could argue that not all of the structures and functions are part of there public API. After all, it is pretty rare that someone implements there own rendering engine for something as big, complex as graphviz. But these structures are in the headers that every distribution installs into /usr/include/graphviz/.</p>
<p><strong>Rule #5: If it is in a header which gets installed for the user, it is part of the API. If you have internal details you wish to hide use the <a class="vt-p" href="http://en.wikipedia.org/wiki/Opaque_pointer" target="_blank">PIMPL</a> pattern.</strong></p>
<p>So the end of the story is that I&#8217;ve got my Qt based graphing widget I sought after. But the deployment is less than fun. Because I distribute sources I need to test that it compiles on all sorts of distributions. All of this could have been so much simpler if they just planned ahead and had a version friendly API.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/11/04/how-not-to-maintain-an-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Fun with graphs</title>
		<link>http://blog.codef00.com/2009/04/22/fun-with-graphs/</link>
		<comments>http://blog.codef00.com/2009/04/22/fun-with-graphs/#comments</comments>
		<pubDate>Wed, 22 Apr 2009 22:30:14 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[edb]]></category>
		<category><![CDATA[graphs]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=45</guid>
		<description><![CDATA[So I figured that I would post some of the progress with EDB. I&#8217;ve been very happy with the function analysis engine that I developed, but there is one thing that it completely ignores, basic block analysis. Of course in &#8230; <a href="http://blog.codef00.com/2009/04/22/fun-with-graphs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>So I figured that I would post some of the progress with EDB. I&#8217;ve been very happy with the function analysis engine that I developed, but there is one thing that it completely ignores, basic block analysis. Of course in order to identify functions it does technically break things down into blocks, but this information is discarded when a whole function is identified.</p>
<p><span id="more-45"></span>The main reason for this is that I had no real practical way to display this information in a useful way to users. A list of blocks wouldn&#8217;t do, there would simply be to many for anyone to make sense of them. Some other tools have a nice solution though&#8230;graphs <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>So I figured that it&#8217;s time EDB got a graphing plugin of sorts. And that&#8217;s where my focus has been lately. Finally after playing with the <strong>awesome </strong><a href="http://doc.trolltech.com/4.5/qgraphicsview.html" target="_blank">QGraphicsView</a> API, I have some results that are worth noting.</p>
<p style="text-align: center;"><a href="http://blog.codef00.com/wp-content/uploads/2009/04/edb_graph1.png" target="_blank"><img class="aligncenter size-full wp-image-47" title="edb_graph1" src="http://blog.codef00.com/wp-content/uploads/2009/04/edb_graph1.png" alt="edb_graph1" width="407" height="265" /></a></p>
<p style="text-align: left;">As you can see, it is looking pretty nice. All of the nodes are draggable so if you don&#8217;t like how it is layed out, you can adjust it. Of course it isn&#8217;t quite ready yet, otherwise I would have just tossed it into EDB and bumped the version. There are two major things I need to figure out.</p>
<ol>
<li>How big do I make the whole scene? Right now I just go with &#8220;very big&#8221;, but eventually, I&#8217;ll have to figure this out based on the content. This is very dependant on issue #2 though&#8230;</li>
<li>I have no automatic layout engine. Currently in my test code, I&#8217;ve manually placed each node. This is likely to prove very difficult, but I&#8217;ll get there (Obviously if any graph experts out there want to help, feel free to email me <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> ).</li>
</ol>
<p>Beyond that, I&#8217;m feeling pretty good about how it works.</p>
<p>You may be wondering why I didn&#8217;t just use <a href="http://www.graphviz.org/">GraphViz</a>. Well, to be honest, I looked into it. But there didn&#8217;t seem to be any nice and simple way to get the results into a Qt widget. As far as I can tell, the API revolves around programatically generating a .dot file, and sending that through one of the graphviz renderer&#8217;s. Then taking the output file and finally displaying it. I don&#8217;t like all the temporary files and the dependency on external programs. I&#8217;m not a fan of &#8220;front-ends&#8221; in general, otherwise EDB would just be another GDB front end.</p>
<p>Though if I could do a pure library solution, I could work with the temporary files. Obviously I could have missed something in graphviz, if so, let me know <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .</p>
<p>I hope to have things nice and ready for release soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/04/22/fun-with-graphs/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Micro-optimization is stupid</title>
		<link>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/</link>
		<comments>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/#comments</comments>
		<pubDate>Wed, 11 Feb 2009 16:52:51 +0000</pubDate>
		<dc:creator>Evan Teran</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[c++]]></category>

		<guid isPermaLink="false">http://blog.codef00.com/?p=35</guid>
		<description><![CDATA[I tend to frequent the website stackoverflow.com. It&#8217;s a fantastic website. It allows knowlege to be shared in a unique way. The only problem is, some people have no idea what they are talking about. If there are enough people &#8230; <a href="http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I tend to frequent the website <a href="http://www.stackoverflow.com/" target="_blank">stackoverflow.com</a>. It&#8217;s a fantastic website. It allows knowlege to be shared in a unique way. The only problem is, some people have no idea what they are talking about. If there are enough people who agree with these misguided notions, well then these incorrect answers get up-votes. And the cycle of mis-information repeats. It isn&#8217;t too dissimilar from the various types of incorrect information regarding <a href="http://blog.codef00.com/2007/12/19/windows-on-x86-and-4gb-of-ram/">32-bit machines and 4GB of RAM</a>.</p>
<p><span id="more-35"></span>This isn&#8217;t a problem with stackoverflow.com, it&#8217;s a problem with people who claim things to be the case without actually testing if what they are saying is true. It happens time and time again.</p>
<p>You may be wondering why the title of this blog entry is &#8220;Micro-optimization is stupid&#8221; when I haven&#8217;t even mentioned that yet, well wait no more, here it is. Someone had asked a question which had a simple answer on SO. He was trying to insert a pointer to an object into a list which contained actual objects. I am guessing he is usually a java programmer (this isn&#8217;t an attack of java programmers, just that java&#8217;s syntax for creating references to objects looks very much like the broken c++ he was trying to use).</p>
<p>Someone took it upon themselves to not only give advice on how to correct this trivial error, but also gave some optimization advice for iterating over the list. He recomended something like this:<br />
<code><br />
    for(std::list&lt;Point&gt;::iterator it = l.begin(), end = l.end(); it != end; ++i) {<br />
        /* whatever */<br />
    }<br />
</code><br />
as apposed to this:<br />
<code><br />
    for(std::list&lt;Point&gt;::iterator it = l.begin(); it != l.end(); ++i) {<br />
        /* whatever */<br />
    }<br />
</code><br />
The reality is that there isn&#8217;t a huge amount of difference between the two. The goal of the posters code is to avoid std::list::end() from being called after every iteration of the loop. I felt compelled to point out to the poster that the optimization recomendation was misguided as any sane compiler will nicely optimize that loop so the std::list::end() is only called once. In addition to that std::list::end() is an O(1) operation as mandated by the standard, so even if it were called multiple times, it wouldn&#8217;t make a difference. You&#8217;re trading one memory fetch for another, no real difference.</p>
<p>Of course he argued, people who don&#8217;t know what they are talking about usually do <img src='http://blog.codef00.com/wp-includes/images/smilies/icon_razz.gif' alt=':-P' class='wp-smiley' /> . He started claiming that since the compiler doesn&#8217;t know that the size is constant,  it has to recalculate the size each time, and that this extra function call would cause cache misses and such. See the problem here? There is enough techno-babble to sound convincing! But don&#8217;t worry folks, I was determined to demonstrate my point.</p>
<p>So I responded with a few corrections. Most importantly,  <code>size() != end()</code>, so even if it did need to recalculate <code>size()</code> each time, the size has nothing to do with it.  In addition, certainly if the loop only uses member functions which are const it certainly <strong>can</strong> know that the list hasn&#8217;t changed.  (he of course retorted that while the <code>end()</code>/<code>size()</code> function is const, it&#8217;s result is not, which is just silliness, since end() won&#8217;t change the list, if all other functions don&#8217;t change the list, well then end() will be the same next iteration!). Finally, I sent him a link to some code which looks like this:</p>
<p><code><br />
    // program 1<br />
    #include &lt;list&gt;<br />
    #include &lt;iostream&gt;</p>
<p>    int main() {<br />
        std::list&lt;int&gt; l1;</p>
<p>        l1.push_back(1);<br />
        l1.push_back(2);<br />
        l1.push_back(3);<br />
        l1.push_back(4);</p>
<p>        std::list&lt;int&gt;::iterator end = l1.end();<br />
        for(std::list&lt;int&gt;::iterator it = l1.begin(); it != end; ++it) {<br />
            printf("%d\n", *it);<br />
        }<br />
    }<br />
</code><br />
<code><br />
    // program 2<br />
    #include &lt;list&gt;<br />
    #include &lt;iostream&gt;</p>
<p>    int main() {<br />
        std::list&lt;int&gt; l1;</p>
<p>        l1.push_back(1);<br />
        l1.push_back(2);<br />
        l1.push_back(3);<br />
        l1.push_back(4);</p>
<p>        for(std::list&lt;int&gt;::iterator it = l1.begin(); it != l1.end(); ++it) {<br />
            printf("%d\n", *it);<br />
        }<br />
    }<br />
</code></p>
<p>And asked that he compile them both with g++ -O3 and <strong>look</strong> at the results. Not just assume what some other jackass told him was correct. I had already done this, and knew that the result on the latest g++ is identical. At this point I had a good feeling, knowing I had prevailed&#8230; until he responded with this:</p>
<blockquote><p>GCC 4.01 with g++ -O3 -S produces different assembly outputs and different binaries with vectors and lists. GCC 4.2 produces identical output for lists but different output for vectors. The OP uses a vector, my comment stands.</p></blockquote>
<p>Seriously?! This guy just couldn&#8217;t admit being even slightly wrong. To be clear, the OP used a <strong>list, not a vector</strong>. So at this point he was just making things up without taking the time to read. In addition, I checked and the &#8220;difference&#8221; between the two was more or less cosmetic. Doing the same work in slightly different order (but not repeatedly calling end(), which was the original concern).</p>
<p>Finally, justice came and people started to downvote his answer.  Finally he edited his post to remove the incorrect advice he gave and the downvotes were removed. None of this would have happened if he hadn&#8217;t gotten fixated on silly little micro-optimizations. When will people learn?</p>
<p>Tricks like this may have made a difference in the early days of c++, but modern compilers are suprisingly good at optimization. Let them do their job so that you can do your job!</p>
<p>At this point in time, every compitent developer should know that it is best to do things the simplest, most obvious way first. This is better in many ways, most importantly in maintainability. Everyone can agree that simple and obvious code is easier to understand. Then if after <strong>profiling</strong> you find that a particular segment of code is not performant enough, feel free to go bananas with optimizing the little things in that particular section.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.codef00.com/2009/02/11/micro-optimization-is-stupid/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

