    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Code Critique Competition 121</title>
        <link>https://members.accu.org/index.php/articles/2732</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Student Code Critiques from CVu journal. + CVu Journal Vol 31, #6 - January 2020</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c184/">Journal Columns</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c183/">Code Critique</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c77/">CVu</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c406/">316</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c183-406/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c183+406/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Code Critique Competition 121</h1>
<p><strong>Author:</strong>&nbsp;Bob Schmidt</p>
<p>
<strong>Date:</strong> 03 January 2020 17:13:00 +00:00 or Fri, 03 January 2020 17:13:00 +00:00</p>
<p><strong>Summary:</strong>&nbsp;Set and collated by Roger Orr. A book prize is awarded for the best entry.</p>
<p><strong>Body:</strong>&nbsp;<p class="EditorIntro">Please note that participation in this competition is open to all members, whether novice or expert. Readers are also encouraged to comment on published entries, and to supply their own possible code samples for the competition (in any common programming language) to scc@accu.org.</p>

<p class="EditorIntro">Note: if you would rather not have your critique visible online please inform me. (Email addresses are not publicly visible.)</p>

<h2>Last issueâ€™s code</h2>

<p class="blockquote">Iâ€™m doing some simple text processing to extract sentences from a text document and produce each one on a separate line. Iâ€™m getting a space at the start of the lines and wonder whatâ€™s the best way to change the regexes to remove it?&quot;</p>

<pre class="programlisting">
    $ cat input.txt
    This is the first sentence. And the
    second. This is
    the
    last
    one.
    
    $ sentences input.txt
    This is the first sentence.
     And the second.
     This is the last one.</pre>
	 
<p>Listing 1 contains the code. As always, there are a number of other things you might want to draw to the authorâ€™s attention as well as the presenting problem.</p>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &lt;fstream&gt;
#include &lt;iostream&gt;
#include &lt;iterator&gt;
#include &lt;sstream&gt;
#include &lt;string&gt;
#include &lt;regex&gt;
using namespace std;

int main(int argc, char** argv)
{
  std::ifstream ifs(argv[1]);
  std::stringstream ss;
  char ch;
  while (ifs &gt;&gt; std::noskipws &gt;&gt; ch)
    ss &lt;&lt; ch;

  string s = ss.str();

  smatch m;

  while (regex_search(s, m,
    regex(&quot;[\\s\\S]*?\\.&quot;)))
  {
    std::string sentence(m[0]);
    std::regex whitepace(&quot;[\\s]+&quot;);
    std::regex_replace(
      std::ostream_iterator&lt;char&gt;(std::cout),
      sentence.begin(), sentence.end(),
      whitepace, &quot; &quot;);
    std::cout &lt;&lt; std::endl;
    s = m.suffix().str();
  }
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 1</td>
	</tr>
</table>

<h2>Critiques</h2>

<h3>Pete Cordell &lt;accu@codalogic.com&gt;</h3>

<p>Being one of the few people in the world who actually likes regular expressions, I thought Iâ€™d have a play with this Code Critique.</p>

<p>In the order that thoughts arose in the file, I noticed that the code used the common <code>using namespace std;</code> line but then prefixed many functions and classes with <code>std::</code> anyway. Iâ€™d prefer the code to either rely on the directive or not, and it should commit to one way or the other.</p>

<p>I opted for not using the directive. That said, these days I feel that in a modern language strings should be treated as first class types similar to <code>bool</code>, <code>int</code> and <code>float</code>. I therefore changed <code>using namespace std;</code> to <code>using std::string;</code>.</p>

<p>This does make the primary loop where the majority of the regex work is done somewhat noisy. As much by way of experiment I added statements such as <code>using std::smatch;</code> at the beginning of the function to see how it looked. I actually quite like this as it gives the reader some foresight that these are the sorts of toys this function is going to be dealing with.</p>

<p>Going back to the function declaration for <code>main()</code>, g++ 9.2.0 on Wandbox complained that <code>argc</code> wasnâ€™t used. The simple way to fix this is to do use <code>int main(int, char** argv)</code>.</p>

<p>The reading of the input into a string can actually be done as a one liner:</p>

<pre class="programlisting">
  string s((std::istreambuf_iterator&lt;char&gt;(ifs)),
    std::istreambuf_iterator&lt;char&gt;())</pre>
	
<p>This looks like some weird incantation to me but I guess there are only so many ways that an input stream can be used to initialise a string, so a reader maybe able to guess what was going on even if they werenâ€™t sure.</p>

<p>The core <code>regex</code> in the example is <code>&quot;[\\s\\S]*?\\.&quot;</code>. This relies on the non-default non-greedy matching specification <code>&quot;*?&quot;</code>. To me, this is an advanced <code>regex</code> feature and best avoided if possible. (If nothing else, the syntax looks scary.) The desired goal of the <code>regex</code> is to match anything up to and including the first encountered full-stop. I think this is better expressed using a negative character class match such as <code>&quot;[^.]*\\.&quot;</code>.</p>

<p>The <code>&quot;[^.]*\\.&quot;</code> expression also captures leading whitespace. My simple solution to this is to change the expression to <code>&quot;\\s*([^.]*\\.)&quot;</code>. This skips over the leading whitespace and creates another capture group for what we want. So where in the loop we previously had <code>m[0]</code> for what the whole regular expression captured, I changed this to <code>m[1]</code>.</p>

<p>The <code>&quot;[\\s]+&quot;</code> <code>regex</code> for whitespace is over complicated and can simply be done as <code>&quot;\\s+&quot;</code>.</p>

<p>The last line of the original loop was <code>s = m.suffix().str();</code>. Creating a new string for the subsequent iteration feels like the wrong way to do things. My solution to this was to set up a <code>string</code> iterator of the form <code>string::const_iterator is( s.cbegin() )</code> and then use that in the loop condition as <code>regex_search(is, s.cend(), m, â€¦</code>. At the end of the loopb the iterator is updated using <code>is += m.length()</code>. Whether this is the idiomatic way to do this I donâ€™t know. I look forward to finding out. [<em>Editor: you could use </em><code>is = m.suffix().first;</code>]</p>

<p>My modified code is:</p>

<pre class="programlisting">
  #include &lt;fstream&gt;
  #include &lt;iostream&gt;
  #include &lt;iterator&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  #include &lt;regex&gt;
  using std::string;
  int main(int , char** argv)
  {
    using std::smatch;
    using std::regex_search;
    using std::regex;
    using std::regex_replace;
    std::ifstream ifs( argv[1] );
    string s((std::istreambuf_iterator&lt;char&gt;(ifs)),
      std::istreambuf_iterator&lt;char&gt;());
    smatch m;
    string::const_iterator is( s.cbegin() );
    
    while (regex_search(is, s.cend(), m,
      regex(&quot;\\s*([^.]*\\.)&quot;)))
    {
      string sentence(m[1]);
      regex whitepace(&quot;\\s+&quot;);
      regex_replace(
        std::ostream_iterator&lt;char&gt;(std::cout),
        sentence.begin(), sentence.end(),
        whitepace, &quot; &quot;);
      std::cout &lt;&lt; std::endl;
      is += m.length();
    }
  }</pre>
  
<h3>James Holland &lt;James.Holland@babcockinternational.com&gt;</h3>

<p>In order to make corrections, it is necessary to understand how the existing program works. Regular expressions can be a little difficult to fathom and so I will need to take things one step at a time. The first statement of interest is the <code>regex</code> parameter within the control section of the <code>while</code> loop. Enclosed within the square brackets are two shortcut characters. The first is <code>\\s </code>and denotes a space character. The second is <code>\\S</code> and denotes any character that is not a space. Either of these shortcuts are accepted as a match because they are enclosed in square brackets. This has the effect of matching any character including spaces.</p>

<p>The next <code>regex</code> character is <code>*</code>. This has the effect of including any number of characters in a single match. Sentences consist of many characters and so this required. The next <code>regex</code> character is <code>?</code>, which means stop trying to include characters in the match as soon as a match is found. Lastly, <code>\.</code> signifies that a match is to end in a full stop.</p>

<p>The problem with this regular expression is that it will match sentences with leading spaces as well as sentences without leading spaces. This can be remedied by adding <code>\S</code> to the beginning of the expression. This requires a match not to start with a space. The software now provides the desired result.</p>

<p>Incidentally, <code>(.|\n)</code> could be used in place of <code>[\\s\\S]</code>. The parentheses are required to obtain the correct association of operators but introduces a capture group. To tell the <code>regex</code> that a capture group is not required, <code>?:</code> is inserted after the <code>(</code> character giving <code>(?:.|\n)</code>. It is possible to make the value of <code>reg</code> slightly simpler by using raw literals. This removes the need for the â€˜escapeâ€™ characters and becomes <code>R&quot;(\S[\s\S]*?\.)&quot;</code> and is probably the shortest representation.</p>

<p>It should be noted that in the provided program <code>regex_replace()</code> removes all occurrences of one or more spaces from the sentence and replaces each occurrence with a single space.</p>

<p>There are still some oddities with the program, however.</p>

<p>There is no need to prefix standard library components, such as <code>cout</code> and <code>ifstream</code>, with the namespace <code>std</code> as the <code>using</code> directive has been used to make the contents of the <code>std</code> namespace available. Also, there is no need to read the contents of the file into a <code>stringstream</code> and then copy the <code>stringstream</code> to a <code>string</code>. The file can be read into a <code>string</code> directly. I show how this can be done in my version of the program.</p>

<p>The <code>regex</code> object within the control section of the <code>while</code> loop is created for every iteration of the loop and wastes significant time. The creation of the <code>regex</code> object should be brought outside the <code>while</code> loop and so created only once. The same applies to the <code>whitespace</code> <code>regex</code>.</p>

<p>Using <code>regex_search</code> repeatedly within a loop is not good practice. Although it appears to work in this application, there are <code>regex</code> iterators available that are designed to find every match within a source <code>string</code>. I have adopted this approach in my version of the program.</p>

<p>To make a more self-documenting program, <code>const</code> could be applied to identifiers that do not change their state after initialisation. Such objects include <code>whitespace</code> and <code>sentence</code>. It is not necessary to flush <code>cout</code> after writing every sentence and so a simple <code>'\n'</code> would suffice instead of <code>endl</code>.</p>

<p>It is also possible to add <code>regex_constants::optimize</code> to the <code>regex</code> constructors to optimise for speed but I did not find any improvement in this particular application. Incidentally, the original (corrected) code took about 6.2 seconds to extract 4800 sentences from a test file (but not to display them). The version I provide took 0.1 seconds. An impressive improvement.</p>

<pre class="programlisting">
  #include &lt;fstream&gt;
  #include &lt;iostream&gt;
  #include &lt;iterator&gt;
  #include &lt;regex&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  
  using namespace std;
  
  int main(int arg, char** argv)
  {
    ifstream ifs(argv[1]);
    const string s((istreambuf_iterator(ifs)), {});
    const regex reg(R&quot;(\S[\s\S]*?\.)&quot;);
    const sregex_iterator end;
    const regex whitespace(&quot;[\\s]+&quot;);
    for (sregex_iterator pos(s.cbegin(),
      s.cend(), reg); pos != end; ++pos)
    {
      const string sentence(pos-&gt;str());
      regex_replace(
        ostream_iterator&lt;char&gt;(cout),
        sentence.begin(), sentence.end(),
        whitespace, &quot; &quot;);
      cout &lt;&lt; '\n';
    }
  }</pre>
  
<h3>Hans Vredeveld &lt;accu@closingbrace.nl&gt;</h3>

<p>The last character of a sentence is a period. After this period, we first get some whitespace before the next sentence starts. The regular expression in the <code>regex_search</code> statement treats this whitespace as part of this next sentence. An easy solution is to consume whitespace at the beginning of a sentence separately and not output it:</p>

<p>In the <code>regex_search</code>, change the regular expression to <code>R&quot;([\s]*([\s\S]*?\.))&quot;</code>.</p>

<p>In the body of the <code>while</code>-loop, initialize sentence with <code>m[1]</code>, instead of <code>m[0]</code>.</p>

<p>By the way, I also changed the string literal to a raw string literal for readability. In regular expressions, the backslash is used a lot and this avoids having to double it in the string literal.</p>

<p>Now that we have solved the main issue, letâ€™s see what else we can improve. The first thing is the inconsistent use of functions and types from the <code>std</code> namespace. Most of the time they are used by prefixing them with <code>std::</code>, but on some occasions (declaration of <code>s</code> and <code>m</code>, use of the unnamed <code>regex</code> object in the <code>while</code>-statement) they are found because of the using-directive at line 7. I have a strong preference to not use <code>using</code>-directives and would remove it. The types and functions will have to be prefixed with <code>std::</code>. Note that, because of ADL, <code>regex_search</code> still will be found in namespace <code>std</code> without prefixing it with the namespace.</p>

<p>Leaving the code that reads the file as is for now, we see a <code>while</code>-loop that loops over the string <code>s</code> that is defined before the loop and updated in the last statement of the loop body. We can replace this by a <code>for</code>-loop with an <code>sregex_iterator</code> as loop variable:</p>

<pre class="programlisting">
  std::string s = ss.str();
  std::regex re(R&quot;([\s]*([\s\S]*?\.))&quot;);
  for (std::sregex_iterator it(s.begin(),
       s.end(), re);
       it != std::sregex_iterator();
       ++it)</pre>
	   
<p>The initialization of sentence has to be updated to use <code>*it</code> instead of <code>m</code> (that is no longer used).</p>

<p>This change also improves performance. A crude performance measurement with a large input file (the original test input concatenated 1,000 times) shows that execution time was reduced from roughly 1.5 seconds to 0.6 seconds (on a Linux laptop with a 4-core Intel i7@2.20GHz and 16GB).</p>

<p>In the loop bodyb a sequence of whitespace characters in the sentence is replaced by a single space for each sentence separately. It is more efficient to do this once on the entire input before entering the loop:</p>

<pre class="programlisting">
  std::regex whitespace(R&quot;([\s]+)&quot;);
  std::string s = std::regex_replace(ss.str(),
      whitespace, &quot; &quot;);</pre>
	  
<p>The loop body is now reduced to simply streaming to <code>std::cout</code> (also <code>std::endl</code> is replaced by <code>'\n'</code> to avoid flushing the buffer after each line):</p>

<pre class="programlisting">
    std::cout &lt;&lt; (*it)[1] &lt;&lt; '\n';</pre>
	
<p>As for the execution time, we are now down to an execution time of about 0.08 seconds on the same input as above.</p>

<p>If we include the reading from file, we now fill the string <code>s</code> by reading the file one character at a time, including whitespaces, and then replace each sequence of whitespaces by a single space. We can combine these actions by reading one word (non-whitespace characters delimited by whitespace characters) at a time, while skipping whitespace and precede the words with a space when putting them in the <code>stringstream</code>. To keep the scope of the variable containing the words local to the loop, we change the <code>while</code>-loop to a <code>for</code>-loop and declare the variable in the <code>init</code> expression of the <code>for</code>-statement. The execution time with the large input file now goes down to about 0.03 seconds.</p>

<p>After all this refactoring, the entire program looks as follows:</p>

<pre class="programlisting">
  #include &lt;fstream&gt;
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  #include &lt;regex&gt;
  int main(int argc, char** argv)
  {
    std::ifstream ifs(argv[1]);
    std::stringstream ss;
    for (std::string word; ifs &gt;&gt; word;)
      ss &lt;&lt; ' ' &lt;&lt; word;
    std::string s = ss.str();
    std::regex re(R&quot;([\s]*([\s\S]*?\.))&quot;);
    for (std::sregex_iterator it(s.begin(),
      s.end(), re);
      it != std::sregex_iterator();
      ++it)
    std::cout &lt;&lt; (*it)[1] &lt;&lt; '\n';
  }</pre>
  
<p>There are still some opportunities for change/improvement left. I will just remark on them here.</p>

<p>We now have a program with only one regular expression in it. We could replace this by using <code>std::find</code>, <code>std::string::find</code> or friends, but then we would have to manually skip over the spaces between sentences. That would make our program more complex, and I like the simplicity that we have now with the regular expression. Also, it would be interesting to see what compile-time regular expressions would do for this code.</p>

<p>With a very small change to the regular expression, the program can also handle sentences ending in an exclamation point or question mark. It will be more difficult to handle the decimal point in numbers with a fractional part properly.</p>

<p>When reading the file, the program does not do any error handling of its own. Most of the errors that need to be handled are already handled by <code>std::ifstream</code>, but that doesnâ€™t give any feedback to the user. The one case that is not handled and that leads to undefined behaviour, is when <code>argc == 0</code>. In that case, <code>argv[1]</code> is undefined. (If <code>argc == 1</code>, <code>argv[1] </code>is a null pointer.)</p>

<h2>Commentary</h2>

<p>This critique was in part generated by some discussion about the inefficiency of the C++ <code>regex</code> library. While I believe that there are genuine issues with the specification of the library, this critique demonstrates that at least <em>some</em> of the problems are due to inappropriate use of the library.</p>

<p>One key item to improve the use of <code>regex</code> is the understanding that there are two parts to the process â€“ firstly generating the regular expression and second applying it to the target. In this critique, the creation of the <code>regex</code> objects each time round the loop is particularly troubling. There was thought given, when the <code>regex</code> library was written, to supporting regular expressions in an idiomatic C++ manner, and some of the solutions provided above demonstrate this.</p>

<p>The other part of the commentary is to recommend using raw string literals (available since C++11) for strings where the number of escape characters would otherwise make the string unreadable. This is very common with <code>regex</code> expressions as use of the backslash is common, and each use must be escaped when using a standard string literal.</p>

<p>Regular expressions were the first motivating example in the original proposal, N2146, including a line from a C++ program which read:</p>

<pre class="programlisting">
&quot;('(?:[^\\\\']|\\\\.)*'|\&quot;(?:[^\\\\\&quot;]|\\\\.)*\&quot;)|&quot;</pre>

<p>While Hans noted that the code invoked undefined behaviour if <code>argc</code> was 0, no-one pointed out that the program crashes (typically) if <code>argc</code> was 1 (as the argument is expected to point to a null terminated character string). I would like to have seen this case handled, for example by writing a usage message, to improve the usability of the program.</p>

<h2>The winner of CC 120</h2>

<p>All the critiques resolved the presenting issue of the leading spaces â€“ although in slightly different fashions. Iâ€™m not sure there is necessarily a â€˜best wayâ€™ â€“ I think it depends what fits in best with the direction of the solution.</p>

<p>The solutions also improved the performance of the original code; I did some basic performance measurement of the three solutions and Pete and Jamesâ€™s solutions seem of similar speed while Hansâ€™s is noticeably faster (a result of the change he made to perform whitespace handling on input)</p>

<p>Pete made a good call to remove the use of the non-greedy matching specification (<code>&quot;*?&quot;</code>) in the original <code>regex</code>; I agree with him that this can make the regular expression harder to understand for the reader.</p>

<p>I think this critique is a good place to use <code>sregex_iterator</code> and I was pleased to see two solutions did so. I think this better expresses the intent of the example; it may also be more performant (but this depends upon the standard library implementation being used.)</p>

<p>Jamesâ€™s solution nicely illustrates the use of CTAD (Class Template Argument Deduction) in the initialisation of the string <code>s</code> using <code>istream_iterator</code> â€“ you may need to enable experimental C++ support in your compiler to get this to compile pending the C++20 standard.</p>

<p>Hans also pointed out a few problems with the code â€“ such as in handling sentences ending with punctuation and the lack of error handling and so I am awarding him the prize for this issueâ€™s critique. </p>

<h2>Code Critique 121</h2>

<p>(Submissions to scc@accu.org by February 1st)</p>

<p class="blockquote">I wanted to offload logging to the console from my main processing threads, so I thought Iâ€™d try to write a simple asynchronous logger class to help me do that (and hopefully learn something about threading while Iâ€™m doing it). Unfortunately it only prints the first line (or sometimes the first couple) and Iâ€™m not really sure how best to debug this as the program doesnâ€™t seem to behave quite the same way in the debugger.</p>

<pre class="programlisting">
     $ queue.exe
     main thread
     Argument 0 = queue.exe</pre>
	 
<p class="blockquote">or sometimes only:</p>

<pre class="programlisting">
     $ queue.exe
     main thread</pre>

<p>The coding is in three listings:</p>

<ul>
	<li>Listing 2 contains <span class="filename">async logger.h</span></li>
	<li>Listing 3 contains <span class="filename">async logger.cpp</span> </li>
	<li>Listing 4 contains <span class="filename">queue.cpp</span>.</li>
</ul>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#pragma once

#include &lt;iostream&gt;
#include &lt;queue&gt;
#include &lt;string&gt;
#include &lt;thread&gt;

using std::thread;

class async_logger
{
  bool active_;
  std::queue&lt;std::string&gt; queue_;
  thread thread { [this]() { run(); } };
  
  void run();
  
public:
  async_logger();
  ~async_logger();
  void log(const std::string &amp;str);
};
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 2</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &quot;async_logger.h&quot;
#include &lt;iostream&gt;
using std::thread;

// This runs in a dedicated thread
void async_logger::run()
{
  while (active_)
  {
    if (!queue_.empty())
    {
      std::cout &lt;&lt; queue_.front() &lt;&lt; '\n';
      queue_.pop();
    }
  }
}
async_logger::async_logger()
{
  active_ = true;
  thread_.detach();
}
async_logger::~async_logger()
{
  active_ = false;
}

// queue for processing on the other thread
void async_logger::log(const std::string &amp;str)
{
  queue_.emplace(str);
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 3</td>
	</tr>
</table>

<table class="sidebartable">
	<tr>
		<td>
			<pre class="programlisting">
#include &quot;async_logger.h&quot;

int main(int argc, char **argv)
{
  async_logger logger;
  logger.log(&quot;main thread&quot;);
  thread test1([&amp;logger]() {
    logger.log(&quot;testing thread 1&quot;);
  });
  for (int idx = 0; idx &lt; argc; ++idx)
  {
    logger.log(&quot;Argument &quot;
      + std::to_string(idx) + &quot; = &quot;
      + argv[idx]);
  }
  logger.log(&quot;main ending&quot;);
  test1.join();
}
			</pre>
		</td>
	</tr>
	<tr>
		<td class="title">Listing 4</td>
	</tr>
</table>

<p>You can also get the current problem from the accu-general mail list (next entry is posted around the last issueâ€™s deadline) or from the ACCU website (<a href="http://accu.org/index.php/journal">http://accu.org/index.php/journal</a>). This particularly helps overseas members who typically get the magazine much later than members in the UK and Europe.</p>

<p class="bio"><span class="author"><b>Roger Orr</b></span> Roger has been programming for over 20 years, most recently in C++ and Java for various investment banks in Canary Wharf and the City. He joined ACCU in 1999 and the BSI C++ panel in 2002.</p>
</p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
