<?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/"
		xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
	>
<channel>
	<title>Comments on: Fun with C++: Macro Pitfalls, Batch 1!</title>
	<atom:link href="http://yaserzt.com/blog/archives/172/feed" rel="self" type="application/rss+xml" />
	<link>http://yaserzt.com/blog/archives/172</link>
	<description>Shadowlessness, and how it feels.</description>
	<lastBuildDate>Fri, 30 Dec 2011 19:29:04 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
	<item>
		<title>By: Hieu Le Trung</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-18664</link>
		<dc:creator>Hieu Le Trung</dc:creator>
		<pubDate>Wed, 06 May 2009 07:36:37 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-18664</guid>
		<description>Thanks, it&#039;s very helpful to understand macro :)</description>
		<content:encoded><![CDATA[<p>Thanks, it&#8217;s very helpful to understand macro <img src='http://yaserzt.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: yzt</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-784</link>
		<dc:creator>yzt</dc:creator>
		<pubDate>Sat, 01 Mar 2008 22:28:54 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-784</guid>
		<description>@MatGill(5):
Yeah, it is supposed to, but I reserved place 0 for the  length of the array! ;-)

@Munk(4):
First, welcome!

What you say about the times that there&#039;s no all-correct way to write a macro is absolutely correct. That&#039;s why I suggest inline functions, or inline function templates.

The BLOCK_SET macro is written for plain C? As I understand, C99 now supports inline functions. Were you worried about performance that you implemented this as a macro? I guess you were reluctant to use a function because then you had to pass the first three arguments as pointers and add a level of indirection. Am I correct? Wouldn&#039;t the optimizer realize the reason for the pointers (persistence of changes as opposed to real pointer semantics) and optimize the overhead away? Have you actually tried this and inspected the assembly code? (Of course, it&#039;s too much work most of the time.)
I&#039;m curious because my experience with plain C is really really limited. So I grab every opportunity not to lose touch!</description>
		<content:encoded><![CDATA[<p>@MatGill(5):<br />
Yeah, it is supposed to, but I reserved place 0 for the  length of the array! <img src='http://yaserzt.com/blog/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>@Munk(4):<br />
First, welcome!</p>
<p>What you say about the times that there&#8217;s no all-correct way to write a macro is absolutely correct. That&#8217;s why I suggest inline functions, or inline function templates.</p>
<p>The BLOCK_SET macro is written for plain C? As I understand, C99 now supports inline functions. Were you worried about performance that you implemented this as a macro? I guess you were reluctant to use a function because then you had to pass the first three arguments as pointers and add a level of indirection. Am I correct? Wouldn&#8217;t the optimizer realize the reason for the pointers (persistence of changes as opposed to real pointer semantics) and optimize the overhead away? Have you actually tried this and inspected the assembly code? (Of course, it&#8217;s too much work most of the time.)<br />
I&#8217;m curious because my experience with plain C is really really limited. So I grab every opportunity not to lose touch!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: MatGill</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-774</link>
		<dc:creator>MatGill</dc:creator>
		<pubDate>Sat, 01 Mar 2008 09:31:54 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-774</guid>
		<description>I thought counting was supposed to start at zero :)</description>
		<content:encoded><![CDATA[<p>I thought counting was supposed to start at zero <img src='http://yaserzt.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
	</item>
	<item>
		<title>By: The Munk</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-765</link>
		<dc:creator>The Munk</dc:creator>
		<pubDate>Fri, 29 Feb 2008 22:14:35 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-765</guid>
		<description>indeed, some of the problems are unsolvable
#define MAX(x,y) ((x)&gt;(y)?(x):(y))
will still fail* for:
MAX(i++,y++)
* (maybe, the postfix increment operator is actually undefined for that case)

But, any of the OOP problems can be solved easily with wrapping, which should be done anyways...in example, a macro from the project I am working on right now(in c)

#define BLOCK_SET(CODEV,MAINV,HEADV,VALUE) \
{ \
if( SYS_STATE.MODE == CODE ) \
CODEV=VALUE; \
else if(SYS_STATE.MODE == EXPRESSION ) \
MAINV = VALUE; \
else if( SYS_STATE.MODE == EXPRESSION ) \
HEADV=VALUE; \
}

The thing you need to remember that writing tons of macros will require lisp-like paren usage</description>
		<content:encoded><![CDATA[<p>indeed, some of the problems are unsolvable<br />
#define MAX(x,y) ((x)&gt;(y)?(x):(y))<br />
will still fail* for:<br />
MAX(i++,y++)<br />
* (maybe, the postfix increment operator is actually undefined for that case)</p>
<p>But, any of the OOP problems can be solved easily with wrapping, which should be done anyways&#8230;in example, a macro from the project I am working on right now(in c)</p>
<p>#define BLOCK_SET(CODEV,MAINV,HEADV,VALUE) \<br />
{ \<br />
if( SYS_STATE.MODE == CODE ) \<br />
CODEV=VALUE; \<br />
else if(SYS_STATE.MODE == EXPRESSION ) \<br />
MAINV = VALUE; \<br />
else if( SYS_STATE.MODE == EXPRESSION ) \<br />
HEADV=VALUE; \<br />
}</p>
<p>The thing you need to remember that writing tons of macros will require lisp-like paren usage</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: yzt</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-753</link>
		<dc:creator>yzt</dc:creator>
		<pubDate>Fri, 29 Feb 2008 09:40:43 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-753</guid>
		<description>What you propose is valid and it does solve the problem in this particular case, but multi-statement macros that cannot be turned into a single statement (or expression) are not uncommon. My point here was not about how do solve this case, but how to generally write such macros in a safer manner.
As I mentioned, the solution you propose does work and its applicability usually surpasses what people think! However, for the sake of the argument, I have to say that there is a couple of minor things that bother me about this way of writing this macro.
&lt;pre lang=&quot;cpp&quot; lines=&quot;1&quot;&gt;
#define SAFE_DELETE(ptr)  delete (ptr), (ptr) = 0

// Case 0
x = SAFE_DELETE(p);
/*  The above causes a compile error to be generated (as might be expected)
 * because the return type of &quot;delete&quot; is &quot;void&quot;, but we are encountering a
 * case of &quot;Operator Mishaps From Hell&quot;, because the assignment operator
 * precedes the comma, we are not taking the return value of the whole
 * macro, but only of a part of it. We are lucky that the return value of
 * &quot;delete&quot; is &quot;void&quot;, since it generates a compile error almost all the time.
 */

// Case 1
x = y = SAFE_DELETE(s);
x = (y = SAFE_DELETE(s));
// These won&#039;t compile, but think what would happen if they did!

// Case 2
for ( ; SAFE_DELETE(s); );
/*  This one _will_ compile with not even a warning at normal warning
 * levels. I don&#039;t think anyone would do this, not with this macro,
 * but can we say that for all such macros?
 * We need to enclose the macro in parentheses, to make its behavior
 * consistent, don&#039;t we?
 */

// Case 3
#define SAFE_DELETE(ptr)  (delete (ptr), (ptr) = 0)

x = SAFE_DELETE(s);
for ( ; SAFE_DELETE(s); );
/*  Now, the above compile and work consistently, but their behavior
 * is no longer consistent with the &quot;delete&quot; operator, which
 * is supposed to return &quot;void&quot;, not a pointer.
 * I must admit though, that this is a very small problem and can
 * be over-looked. After all, we have changed the name of our macro
 * and no one should expect it to behave exactly as &quot;delete&quot;.
 */
&lt;/pre&gt;</description>
		<content:encoded><![CDATA[<p>What you propose is valid and it does solve the problem in this particular case, but multi-statement macros that cannot be turned into a single statement (or expression) are not uncommon. My point here was not about how do solve this case, but how to generally write such macros in a safer manner.<br />
As I mentioned, the solution you propose does work and its applicability usually surpasses what people think! However, for the sake of the argument, I have to say that there is a couple of minor things that bother me about this way of writing this macro.</p>
<pre lang="cpp" lines="1">
#define SAFE_DELETE(ptr)  delete (ptr), (ptr) = 0

// Case 0
x = SAFE_DELETE(p);
/*  The above causes a compile error to be generated (as might be expected)
 * because the return type of "delete" is "void", but we are encountering a
 * case of "Operator Mishaps From Hell", because the assignment operator
 * precedes the comma, we are not taking the return value of the whole
 * macro, but only of a part of it. We are lucky that the return value of
 * "delete" is "void", since it generates a compile error almost all the time.
 */

// Case 1
x = y = SAFE_DELETE(s);
x = (y = SAFE_DELETE(s));
// These won't compile, but think what would happen if they did!

// Case 2
for ( ; SAFE_DELETE(s); );
/*  This one _will_ compile with not even a warning at normal warning
 * levels. I don't think anyone would do this, not with this macro,
 * but can we say that for all such macros?
 * We need to enclose the macro in parentheses, to make its behavior
 * consistent, don't we?
 */

// Case 3
#define SAFE_DELETE(ptr)  (delete (ptr), (ptr) = 0)

x = SAFE_DELETE(s);
for ( ; SAFE_DELETE(s); );
/*  Now, the above compile and work consistently, but their behavior
 * is no longer consistent with the "delete" operator, which
 * is supposed to return "void", not a pointer.
 * I must admit though, that this is a very small problem and can
 * be over-looked. After all, we have changed the name of our macro
 * and no one should expect it to behave exactly as "delete".
 */
</pre>
]]></content:encoded>
	</item>
	<item>
		<title>By: hadi</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-752</link>
		<dc:creator>hadi</dc:creator>
		<pubDate>Fri, 29 Feb 2008 08:37:04 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-752</guid>
		<description>what about:
#define SAFE_DELETE(ptr) delete (ptr), (ptr) = 0
?</description>
		<content:encoded><![CDATA[<p>what about:<br />
#define SAFE_DELETE(ptr) delete (ptr), (ptr) = 0<br />
?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: hadi</title>
		<link>http://yaserzt.com/blog/archives/172/comment-page-1#comment-750</link>
		<dc:creator>hadi</dc:creator>
		<pubDate>Fri, 29 Feb 2008 07:40:55 +0000</pubDate>
		<guid isPermaLink="false">http://yaserzt.com/blog/2008/02/29/fun-with-c-macro-pitfalls-batch-1/#comment-750</guid>
		<description>nice!</description>
		<content:encoded><![CDATA[<p>nice!</p>
]]></content:encoded>
	</item>
</channel>
</rss>

