Channels ▼

Matthew Wilson

Dr. Dobb's Bloggers

Superfluous Curly Braces as Semantic Guides?

May 22, 2010

Working today I noticed that I tend to use use curly-braces to rank different levels of semantic operations. Never before having consciously thought about the rules applied, I thought it fit to discuss it with you, gentle readers, and see whether I'm not alone.I'm currently writing/modifying several C-family source-code analysis tools, to support my current commercial activities. (I'm acting as an expert witness on a software intellectual property dispute case. It's very interesting stuff, and has peculiar logical and physical limitations that bring to light many programming issues one tends to forget in the practically unconstrained resource environment of much desktop software development, so you can expect a steady stream of posts covering a wide range of topics in the coming months.)

Anyway, in making some modifications yesterday I noticed that I'd chosen one bracing style over another, and I wondered why I'd done so?

Here's one possible layout of the code:

{ for(string_set_t::const_iterator i = exemptions.begin(); i != exemptions.end(); ++i)
{
 string_t s = *i;
 stlsoft::trim_all(s);
 if(s.empty())
 {
  continue; // Skip empty
 }
 else if('#' == s[0])
 {
  continue; // Skip comment
 }
 else if(NULL != ::strpbrk(s.c_str(), "?*"))
 {
  Pattern_ptr_t pattern(new shwild::Pattern(s.c_str(), shwildPatternFlags));
  exemptionsPatterns.push_back(pattern);
 }
 else
 {
  exemptionNames.insert(s);
 }
}}

Yet I didn't do it that way. Without pause I wrote the following instead:

{ for(string_set_t::const_iterator i = exemptions.begin(); i != exemptions.end(); ++i)
{
 string_t s = *i;
 stlsoft::trim_all(s);
 if(s.empty())
 {
  continue; // Skip empty
 }
 else if('#' == s[0])
 {
  continue; // Skip comment
 }
 else
 {
  if(NULL != ::strpbrk(s.c_str(), "?*"))
  {
   Pattern_ptr_t pattern(new shwild::Pattern(s.c_str(), shwildPatternFlags));
   exemptionsPatterns.push_back(pattern);
  }
  else
  {
   exemptionNames.insert(s);
  }
 }
}}

The issue that intrigues me is why I've gone to the trouble of creating an extra level of block indentation (and consumed an extra line of source into the bargain)?

As far as I can determine there are two reasons: one worthy, one prosaic.

Dealing with the less glamorous first, I should observe that this is a heavily file-system and input dependent program, so I've eschewed unit-testing for the application (though not for the constituent libraries!) in favour of the debugger. By selecting the second layout I can apply a single breakpoint (on the if + strpbrk statement), rather than two on the latter two blocks.

This, in turn, is a hint to the more worthy reason. The first two conditional blocks are both dealing with "lines outside our interest". The program in question performs analysis of #include statements in C/C++ source, and the code sample shows some of the logic to the filtering out from the results set those includes designated by the user as being not-of-interest. As is clearly shown, it filters by name (the exemptionNames set) or by pattern (the exemptionsPatterns sequence of shwild pattern instances). So, by using the extra block, I've highlighted/separated the "important" logic from the mundane.

Granted, nothing about this is rocket surgery. But I've been writing code for more than two decades and have never noticed before that I do this. (As you'd expect, I've now looked back at lots of other code, and I've been doing it for a long time.)

I'd be interested to hear from other readers what they think of this, and what other ways in which they do (semantically unnecessary) things that aid in code transparency. I'm especially interested to hear about such things in other languages, even those outside the C-family.


Before I go, I'd like to comment on a couple of other issues that might have the ardent C++ programmers amongst you scratching your heads. First, the use of continue. I've met plenty of chap(ette)s who've suggested that continue is a design smell. In this case, due to the use of else the two continues are actually superfluous. The reason I use them is (i) a continue; statement is clearer than an empty block, a ;, or combining the two if conditional expressions, and (ii) I believe it's more resistant to accidental damage during maintenance: one would only have to leave off an else and things would go rather badly.

Second, my use of the enclosing braces around the for statement. As explained in Imperfect C++, I use this technique to avoid any clash between old and new for-statement initialiser semantics. Putting it in a block unambiguously defines its scope, and makes it compatible with any (version of any) C++ compiler.

Finally, my use of strpbrk(). This one's arguably less defensible. The fact is, I just don't like the std::basic_string class interface, and think it has way too many methods. No doubt I could have used find_first_of(), but then I'd have to be testing against std::string::npos, which doesn't make the code clearer to me. (Or, it could be that I'm really an old C programmer at heart, and am just an inconsistent hypocrit!)

Related Reading


More Insights






Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

 
Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.
 


Video