<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: More GList anti-patterns</title>
	<atom:link href="http://blog.barisione.org/2009-07/more-glist-anti-patterns/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/</link>
	<description></description>
	<lastBuildDate>Mon, 16 Jan 2012 11:53:14 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
	<item>
		<title>By: Benjamin Otte</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1937</link>
		<dc:creator>Benjamin Otte</dc:creator>
		<pubDate>Fri, 17 Jul 2009 17:17:28 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1937</guid>
		<description>Oh yeah, I missed the &quot;do something else&quot; part. I thought the second loop just unreffed the items.</description>
		<content:encoded><![CDATA[<p>Oh yeah, I missed the &#8220;do something else&#8221; part. I thought the second loop just unreffed the items.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: liberforce</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1936</link>
		<dc:creator>liberforce</dc:creator>
		<pubDate>Fri, 17 Jul 2009 15:49:23 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1936</guid>
		<description>@Benjamin:
Marco said that it didn&#039;t work, not that it crashed...

The developer wanted the second loop to use the data items, but is never executed. 

Moreover, if the second loop was corrected, the fact that the developer wants to free the items and the list would lead to a crash...

So it&#039;s just not the developer wanted to do, which was it seems something like this :

GList *list = e_vcard_get_attributes (evcard);
GList *l;
for (l = list; l != NULL; l = l-&gt;next)
{
  /* Do something */
  /* Do something else */
}</description>
		<content:encoded><![CDATA[<p>@Benjamin:<br />
Marco said that it didn&#8217;t work, not that it crashed&#8230;</p>
<p>The developer wanted the second loop to use the data items, but is never executed. </p>
<p>Moreover, if the second loop was corrected, the fact that the developer wants to free the items and the list would lead to a crash&#8230;</p>
<p>So it&#8217;s just not the developer wanted to do, which was it seems something like this :</p>
<p>GList *list = e_vcard_get_attributes (evcard);<br />
GList *l;<br />
for (l = list; l != NULL; l = l-&gt;next)<br />
{<br />
  /* Do something */<br />
  /* Do something else */<br />
}</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Benjamin Otte</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1935</link>
		<dc:creator>Benjamin Otte</dc:creator>
		<pubDate>Fri, 17 Jul 2009 15:17:15 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1935</guid>
		<description>If you wanna mess it up in C++ (which you cannot as easily in C), you&#039;d write:
list lst = evcard.attributes();
And then you&#039;d get a g_list_copy().

But Marco, what went wrong about that code? The second loop doesn&#039;t run, g_free (NULL) is fine too. So it should just work (even though it looks very bad).</description>
		<content:encoded><![CDATA[<p>If you wanna mess it up in C++ (which you cannot as easily in C), you&#8217;d write:<br />
list lst = evcard.attributes();<br />
And then you&#8217;d get a g_list_copy().</p>
<p>But Marco, what went wrong about that code? The second loop doesn&#8217;t run, g_free (NULL) is fine too. So it should just work (even though it looks very bad).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pierre Phaneuf</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1934</link>
		<dc:creator>Pierre Phaneuf</dc:creator>
		<pubDate>Fri, 17 Jul 2009 15:17:13 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1934</guid>
		<description>Whoever wrote this would find a way to make a disaster out of it in C++ just as much as in C, I&#039;m sure.

I don&#039;t know much about using GLib (but I do know how a linked list works!), but on top of what Marco said was wrong about the iteration itself (which you can screw up in C++ in a few ways, most easily by modifying the list itself while iterating, if you&#039;re not careful), imagining that he moved the unref to the first list or correctly kept a copy of the head pointer, he would be leaving behind what would look like a populated list, full of dangling pointers to memory that has (probably, it&#039;s a refcount, after all) been freed. If he&#039;s going to delete the items, he should also delete the list nodes.

Most of all, he doesn&#039;t understand ownership correctly, not having bothered to check who&#039;s the owner of e_vcard_get_attributes()&#039;s return value. There&#039;s an advantage to C++ here in theory, since in C you have to check the documentation, or the code of that function in order to know whether you take ownership or not, but in C++ you can codify it with smart pointers, and figure it out simply looking at the function signature. But this guy, if he wrote a function like e_vcard_get_attributes(), he&#039;d probably used shared_ptr everywhere, using the &quot;big hammer that works most of the time (but gives the nearly impossible to debug memory leaks sometimes, oh well)&quot;, because he simply doesn&#039;t understand ownership.

C++ and fancy smart pointers don&#039;t free you from having to understand what&#039;s going on, it just helps with the tedium of dealing with the details. You can just say &quot;this object should be owned by a single owner at all time&quot; by using a scoped_ptr, and let the compiler enforce this.

You still have to know you want this in the first place, though!</description>
		<content:encoded><![CDATA[<p>Whoever wrote this would find a way to make a disaster out of it in C++ just as much as in C, I&#8217;m sure.</p>
<p>I don&#8217;t know much about using GLib (but I do know how a linked list works!), but on top of what Marco said was wrong about the iteration itself (which you can screw up in C++ in a few ways, most easily by modifying the list itself while iterating, if you&#8217;re not careful), imagining that he moved the unref to the first list or correctly kept a copy of the head pointer, he would be leaving behind what would look like a populated list, full of dangling pointers to memory that has (probably, it&#8217;s a refcount, after all) been freed. If he&#8217;s going to delete the items, he should also delete the list nodes.</p>
<p>Most of all, he doesn&#8217;t understand ownership correctly, not having bothered to check who&#8217;s the owner of e_vcard_get_attributes()&#8217;s return value. There&#8217;s an advantage to C++ here in theory, since in C you have to check the documentation, or the code of that function in order to know whether you take ownership or not, but in C++ you can codify it with smart pointers, and figure it out simply looking at the function signature. But this guy, if he wrote a function like e_vcard_get_attributes(), he&#8217;d probably used shared_ptr everywhere, using the &#8220;big hammer that works most of the time (but gives the nearly impossible to debug memory leaks sometimes, oh well)&#8221;, because he simply doesn&#8217;t understand ownership.</p>
<p>C++ and fancy smart pointers don&#8217;t free you from having to understand what&#8217;s going on, it just helps with the tedium of dealing with the details. You can just say &#8220;this object should be owned by a single owner at all time&#8221; by using a scoped_ptr, and let the compiler enforce this.</p>
<p>You still have to know you want this in the first place, though!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1933</link>
		<dc:creator>Tim</dc:creator>
		<pubDate>Fri, 17 Jul 2009 14:41:59 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1933</guid>
		<description>Sorry but it&#039;s *not* language independent. For example if I try to mess up the C++ API as badly as the C one I get this:

list&lt;anobject&gt;&amp; lst = evcard.attributes();

for (lst = lst.begin(); lst != lst.end(); ++lst) // doesn&#039;t compile
{
}

delete lst; // doesn&#039;t compile

This clearly has no chance of compiling, unlike the C version.</description>
		<content:encoded><![CDATA[<p>Sorry but it&#8217;s *not* language independent. For example if I try to mess up the C++ API as badly as the C one I get this:</p>
<p>list&lt;anobject&gt;&amp; lst = evcard.attributes();</p>
<p>for (lst = lst.begin(); lst != lst.end(); ++lst) // doesn&#8217;t compile<br />
{<br />
}</p>
<p>delete lst; // doesn&#8217;t compile</p>
<p>This clearly has no chance of compiling, unlike the C version.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Emmanuele Bassi</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1932</link>
		<dc:creator>Emmanuele Bassi</dc:creator>
		<pubDate>Fri, 17 Jul 2009 14:32:28 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1932</guid>
		<description>you have to admire the power of c++, if c++ developers have all the free time to go on random blogs over the web in order to write comments completely missing the point about algorithmic mistakes that are completely language-independant.

either that, or c++ really don&#039;t have anything better to do.</description>
		<content:encoded><![CDATA[<p>you have to admire the power of c++, if c++ developers have all the free time to go on random blogs over the web in order to write comments completely missing the point about algorithmic mistakes that are completely language-independant.</p>
<p>either that, or c++ really don&#8217;t have anything better to do.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: barisione</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1931</link>
		<dc:creator>barisione</dc:creator>
		<pubDate>Fri, 17 Jul 2009 13:44:33 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1931</guid>
		<description>@oliver:
A GList is just an element in the list. So you have something like:
typedef struct GList {
  struct GList *next;
  struct GList *prev;
  gpointer data;
} GList;

Where next points to the next element or to NULL if you are at the end of the least. prev points to the previous element or NULL if it is already the first element.
So just NULL means an empty list.
This is basically the standard way to implement lists, of course high level languages hide this well.

To iterate a list you just do
for (l = list; l != NULL; l = l-&gt;next)
{
}

So at the end of the iteration l will be NULL (i.e. empty list) and calling g_list_first on NULL returns NULL.</description>
		<content:encoded><![CDATA[<p>@oliver:<br />
A GList is just an element in the list. So you have something like:<br />
typedef struct GList {<br />
  struct GList *next;<br />
  struct GList *prev;<br />
  gpointer data;<br />
} GList;</p>
<p>Where next points to the next element or to NULL if you are at the end of the least. prev points to the previous element or NULL if it is already the first element.<br />
So just NULL means an empty list.<br />
This is basically the standard way to implement lists, of course high level languages hide this well.</p>
<p>To iterate a list you just do<br />
for (l = list; l != NULL; l = l->next)<br />
{<br />
}</p>
<p>So at the end of the iteration l will be NULL (i.e. empty list) and calling g_list_first on NULL returns NULL.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: liberforce</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1930</link>
		<dc:creator>liberforce</dc:creator>
		<pubDate>Fri, 17 Jul 2009 13:40:51 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1930</guid>
		<description>The problem I see is that the first loop scan every item, and when it&#039;s over, list == NULL, so the second call to g_list_first can&#039;t work. And even if list contained the tail, g_list_first would scan the whole list just to find the first element, which is simply stupid.

The two loops seem to have no reason to exist, they should be merged in one single loop doing all the work, an I think calling g_list_first isn&#039;t even necessary, as e_vcard_get_attributes must be smart enough to give you the head of the list...</description>
		<content:encoded><![CDATA[<p>The problem I see is that the first loop scan every item, and when it&#8217;s over, list == NULL, so the second call to g_list_first can&#8217;t work. And even if list contained the tail, g_list_first would scan the whole list just to find the first element, which is simply stupid.</p>
<p>The two loops seem to have no reason to exist, they should be merged in one single loop doing all the work, an I think calling g_list_first isn&#8217;t even necessary, as e_vcard_get_attributes must be smart enough to give you the head of the list&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: rojtberg.net &#187; Why are we using C again?</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1929</link>
		<dc:creator>rojtberg.net &#187; Why are we using C again?</dc:creator>
		<pubDate>Fri, 17 Jul 2009 13:39:48 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1929</guid>
		<description>[...] Gnome. Mostly because you are not forced to use it and so I did not. But recently there were some posts on Planet Gnome which reminded me how inherently broken the core of Gnome is. I mean we have all [...]</description>
		<content:encoded><![CDATA[<p>[...] Gnome. Mostly because you are not forced to use it and so I did not. But recently there were some posts on Planet Gnome which reminded me how inherently broken the core of Gnome is. I mean we have all [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tim</title>
		<link>http://blog.barisione.org/2009-07/more-glist-anti-patterns/comment-page-1/#comment-1928</link>
		<dc:creator>Tim</dc:creator>
		<pubDate>Fri, 17 Jul 2009 11:28:45 +0000</pubDate>
		<guid isPermaLink="false">http://blog.barisione.org/?p=181#comment-1928</guid>
		<description>oliver: I think it&#039;s that he&#039;s changing the value of list and then trying to use it again. The for loops should be something like:

for (GList* node = g_list_first(list); node != NULL; node = g_list_next(node))
{
}</description>
		<content:encoded><![CDATA[<p>oliver: I think it&#8217;s that he&#8217;s changing the value of list and then trying to use it again. The for loops should be something like:</p>
<p>for (GList* node = g_list_first(list); node != NULL; node = g_list_next(node))<br />
{<br />
}</p>
]]></content:encoded>
	</item>
</channel>
</rss>

