<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 <title>C++ Posts · HookRace Blog</title>
 <link href="https://hookrace.net/blog/feed/c++/" rel="self"/>
 <link href="https://hookrace.net/blog/c++/"/>
 <updated>2026-02-10T21:22:29-05:00</updated>
 <id>https://hookrace.net/blog/C++</id>
 <author>
   <name>Dennis Felsing</name>
   <email>dennis@felsing.org</email>
 </author>

 
 <entry>
   <title>HANA C++ Development Environment and Processes</title>
   <link href="https://hookrace.net/blog/hana-cpp-development/"/>
   <updated>2017-12-08T00:00:00-05:00</updated>
   <id>https://hookrace.net/blog/hana-cpp-development</id>
   <content type="html">
     &lt;p&gt;I started working as a C++ developer in the HANA Core Platform team at SAP in Walldorf, Germany more than a year ago. In this time I have gotten some insights into the development environment and processes. I will use this post to illustrate them by the example of adding a small new feature and explaining the steps on the way of getting it released. Some of this will be specific to HANA, some to my team inside HANA, some to my own system.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;&lt;img src=&quot;/public/office.jpg&quot; alt=&quot;Office&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;compilation&quot;&gt;Compilation&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://www.sap.com/products/hana.html&quot;&gt;HANA&lt;/a&gt; is the in-house database powering many of SAP’s products. It is written in C++ with Python tests, and the entire code base lives inside of a single git repository. Hundreds of developers from all around the world are developing on about 10 million lines of C++ code and 15 million lines of Python tests.&lt;/p&gt;

&lt;p&gt;Since HANA is deployed on Linux exclusively, many developers are using Linux on their workstations as well. So far Windows is still supported as a development environment, but this will change in 2019, leaving Linux as the only choice. During day-to-day work you still get to interact with Windows a bit (more than I would prefer), since the Laptop has Windows with the traditional Microsoft Office products on it. But since the actual development happens on Linux, I am happy enough, being able to use the xmonad window manager and software environment I have gotten used to over the last decade.&lt;/p&gt;

&lt;p&gt;HANA is deployed on some &lt;a href=&quot;https://www.sap.com/dmc/exp/2014-09-02-hana-hardware/enEN/appliances.html#categories=certified&amp;amp;order=MemoryDesc&quot;&gt;rather impressive machines&lt;/a&gt;, so in order to test the code adequately the developer workstations are quite beefy as well. I am typing this text from a 20 core / 40 thread Xeon E5-2660 v3 CPU with 128 GB of RAM.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/htop.png&quot; alt=&quot;htop on developer machine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Still compiling HANA is no quick feat. Expect something around 2 hours to build it from scratch on your local machine (illustrated below), and be prepared for some heat output, which is especially noticeable in summer. About half of the colleagues have chosen to move their workstations to the data center and access it remotely instead of working on it locally. Since they are still in one of our SAP buildings in Walldorf, the latency is low enough that a direct X connection is fast enough to be nearly undistinguishable from a local application.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/full-build.png&quot; alt=&quot;Illustration of full HANA build on developer machine&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So if even your beefy developer machine is not enough, how do you compile the product faster? Obviously by combining all of the developer machines together in a compile cluster:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/compile-cluster.png&quot; alt=&quot;Compile Cluster Overview&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Using the compile cluster the build time gets reduced to 16 minutes and now linking takes half of that time. Right now we are still using the gold linker, but after bug fixes lld should cut down the linking time significantly.&lt;/p&gt;

&lt;h2 id=&quot;coding&quot;&gt;Coding&lt;/h2&gt;

&lt;p&gt;But for the code in my team we have another approach. Instead of running the full database and testing using Python tests we have extensive unit tests, literally covering our entire code. Every single line is covered and about 98% of all regions. In order to submit any new code you have to write a unit test that will cover this exact code and include it in the same change.&lt;/p&gt;

&lt;p&gt;Expect 5 minutes to build and run the unit tests from scratch, while building and running them after a change can be as fast as 15 seconds if you didn’t change much and thus not much has to be recompiled.&lt;/p&gt;

&lt;p&gt;People use quite a variety of IDEs and code editors, with Sublime Text, Qt Creator, Eclipse, Visual Studio, emacs and vim being popular choices (in no particular order). Personally I like to work directly on terminals, so I use vim with the &lt;a href=&quot;https://github.com/Valloric/YouCompleteMe&quot;&gt;YouCompleteMe&lt;/a&gt; semantic code completion (and go to definition, type analysis and some more) based on clang/llvm. I use a &lt;a href=&quot;https://github.com/def-/ycmd/commit/2a7124bcb5730f301e3e73a4af81316bbff81926&quot;&gt;custom YCM version&lt;/a&gt; which also shows me the size and alignment of a variable along with its type:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;plangen::PipelineBuilder &amp;amp; =&amp;gt; hex::plangen::PipelineBuilder &amp;amp; (size: 128 B, align: 16 B)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using vim and other command line tools gives me the advantage that I can work just fine as long as I have an SSH connection to my workstation, nothing else required.&lt;/p&gt;

&lt;p&gt;Let’s start by coming up with a useful new feature, tracing the name of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DummyNoRun&lt;/code&gt; operator:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#pragma once
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;hex/planex/framework/OperatorBases.hpp&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;hex/planex/planviz/HasReversedConnection.hpp&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/clang_warnings_hard.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/gcc_warnings_veryhard.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operators&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DummyNoRunOp&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;final&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planviz&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;HasReversedConnection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;NoRunOperator&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;traceOperatorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ltt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namespace operators&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namespace hex&lt;/span&gt;

&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/clang_warnings_end.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/gcc_warnings_end.h&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The implementation is quite simple as well:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DummyNoRunOp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;traceOperatorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ltt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;DummyNoRunOp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For HANA development we use C++14 at this moment. The only unusual thing is that we don’t use the STL, but instead have our own implementation of it, the LTT, which enforces allocator use.&lt;/p&gt;

&lt;p&gt;Our build system wraps around cmake, so it is quite reasonable to use. After adding the cpp file to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; we can locally run our unit tests and verify that nothing broke so far.&lt;/p&gt;

&lt;p&gt;But when we’re compiling the code with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hm b -b Optimized unitHexOperators&lt;/code&gt; (read as: HappyMake build &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Optimized&lt;/code&gt; build [with optimizations and assertions] of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;unitHexOperators&lt;/code&gt; target) we get an unexpected result:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;In file included from ../../hex/plangen/PredInitOpGenerator.cpp:14:0:
../../hex/operators/table/DummyNoRunOp.hpp:16:10: error: ‘virtual void hex::operators::DummyNoRunOp::traceOperatorName(ltt::ostream&amp;amp;) const’ can be marked override [-Werror=suggest-override]
     void traceOperatorName(ltt::ostream&amp;amp; os) const;
          ^~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
ERROR: subcommand failed
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Our warning levels are quite high and all warnings are converted to errors. We even enable warnings in headers (and disable them again at the end in order to not affect other headers that might be included later). In this case the fix is quite simple:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;traceOperatorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ltt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;override&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now our code builds and the unit tests succeed:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ hm b -b Optimized runtests_hex
...
[==========] 728 tests from 147 test cases ran. (11617 ms total)
[  PASSED  ] 728 tests.

  YOU HAVE 2 DISABLED TESTS



Build started:	2017-11-29 16:26:40.459482
Build finished:	2017-11-29 16:26:52.988541
Elapsed time:	12.529s
Command count:	11 (0.9 per sec)
Log directory:	/home/dXXXXXX/src2/build/Optimized/hm_log/build/24
SUCCESS
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;We can also run the code coverage based on our unit tests locally using CheckBot. Unsurprisingly we will find out that our code is not covered yet:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;###############################################################
                  CheckBot - Review Details
###############################################################

###############################################################
                      CheckBot - Summary
###############################################################

______________
General Issues
______________
[CheckHexCodeCoverageClang] (error) hex/operators/table/DummyNoRunOp.cpp: 3 of 3 lines uncovered, 0.00% coverage!
[CheckHexCodeCoverageClang] (error) Line coverage only at 99.99%
[CheckHexCodeCoverageClang] (info) Coverage report can be found at 
file://///home/dXXXXXX/src2/build/linuxx86_64-clangcov-release_hex_with_code_coverage/hexCoverageClang/index.html

CheckBot detected 3 issues (2 errors, 1 info).

	error ... CheckHexCodeCoverageClang  (681748.81 msec)

Overall score: -2

(Legend: ok = +1, info = +1, warning = -1, error = -2)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the bottom of the report we see the “Overall score: -2”, which indicates that our change would not be allowed to be merged by Gerrit. So let’s take a closer look, inside of the linked report we find our code:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/llvm-cov.png&quot; alt=&quot;llvm-cov html report&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Google Test/Mock based unit tests are used to test every part of the code in our team. 100% unit test line coverage is achieved with a development version of llvm-cov. Compared to the gcc based gcov/lcov coverage tools, the LLVM based llvm-cov is in active development, runs much faster and can show you what region of a line is actually covered, allowing finer granularity.&lt;/p&gt;

&lt;p&gt;So let’s write a unit test to satisfy the 100% line coverage requirement:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;hex/operators/table/DummyNoRunOp.hpp&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;hex/test/HexTestBase.hpp&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;hex/planex/test/sandbox/SimpleOperatorSandbox.hpp&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/clang_warnings_hard.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/gcc_warnings_hard.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;warnings/msvc_warnings_hard.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;using&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;testing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;operators&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;namespace&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;test&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UnitDummyNoRunOp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;HexTestBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;protected:&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;planex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;SimpleOperatorSandbox&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;DummyNoRunOp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_sb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()};&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;ltt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ostringstream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_oss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alloc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()};&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;TEST_F&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UnitDummyNoRunOp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;traceOperatorName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m_oss&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;planex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Operator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TraceName&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_sb&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;op&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()};&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;EXPECT_THAT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_oss&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_str&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StrEq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;UnitDummyNoRunOp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namespace test&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namespace operators&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// namespace hex&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;For more coarse-grained testing there are also JSON based component tests as well Python based integration tests available.&lt;/p&gt;

&lt;h2 id=&quot;local-verification&quot;&gt;Local Verification&lt;/h2&gt;

&lt;p&gt;We should also make use of some static code checkers, like clang-format and clang-tidy, before we push the change for remote testing. After all, this ensures a consistent style, fixes some common problems and reduces the mental load on the manual reviewers, since they can rely on the tools instead of complaining about the same trivial nitpick on every change:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;###############################################################
                  CheckBot - Review Details
###############################################################

_____________________________________________
hex/operators/table/test/UnitDummyNoRunOp.cpp
_____________________________________________

[CheckClangFormat] (info) This file is subject to a clang-format code style. CheckBot can reformat the file, see [...]

line 2,0 - 2,35:
#include &quot;hex/test/HexTestBase.hpp&quot;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[CheckClangFormat] (warning) 

 #include &quot;hex/test/HexTestBase.hpp&quot;

should be deleted

line 3,0 - 3,0:
#include &quot;hex/planex/test/sandbox/SimpleOperatorSandbox.hpp&quot;
^
[CheckClangFormat] (warning) 

 #include &quot;hex/test/HexTestBase.hpp&quot;

should be added
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Luckily clang-format can even fix the problem on its own by just adding a parameter.&lt;/p&gt;

&lt;h2 id=&quot;remote-verification&quot;&gt;Remote Verification&lt;/h2&gt;

&lt;p&gt;Finally we can push the change to Gerrit. Now our local work is done and we can start working on something else. Meanwhile automated builds and tests will happen on Linux and Windows machines, as well as a coverage run and various static code analyzers (that we were too lazy to run locally).&lt;/p&gt;

&lt;p&gt;By default just our unit tests and component tests are compiled and executed. But if you want to build the full HANA database and run the Python tests a separate profile is available for that and can be turned on in the Gerrit web interface for specific changes.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/public/gerrit.png&quot; alt=&quot;Gerrit Overview after successful builds&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;code-review&quot;&gt;Code Review&lt;/h2&gt;

&lt;p&gt;Once we have verified that everything works fine on Linux with GCC and Clang as well as Windows with MSVC, we can add a reviewer to our change and set the change to “Ready for Review”. A second reviewer will be chosen automatically. If you are relatively sure that your change will survive the tests and don’t feel like waiting for them, you can of course also add the reviewers straight after submitting the change. But your reviewers might not be happy if they start reviewing already and meanwhile you are pushing new patch sets to fix compilation, tests as well as automatic warnings and suggestions.&lt;/p&gt;

&lt;p&gt;For non-trivial changes further patch sets would follow to integrate the suggestions by the reviewers, until everyone is (reasonably) happy. Finally the change can be submitted and is out of our mind.&lt;/p&gt;

&lt;h2 id=&quot;merging&quot;&gt;Merging&lt;/h2&gt;

&lt;p&gt;Except that there is still one thing missing. Our change is now inside of our component’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; branch, but not yet in the global &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt; branch. The merge from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt; will run a huge number of correctness and performance tests before allowing our changes in. That’s why we only run it after we have collected a few changes. We also use a staging branch &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Initially we merge the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; branch into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt; and try to merge &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Meanwhile everyone can keep developing new features as well as bug fixes on the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; branch.&lt;/li&gt;
  &lt;li&gt;If the merge from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt; fails, a fix for the issue will be submitted to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; and can finally be cherry-picked to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But we don’t merge &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex2orange&lt;/code&gt; again, until we landed in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt; branch. Otherwise the new features from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hex&lt;/code&gt; could cause new test failures while we were fixing the old ones. In the worst case we would never reach &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;orange&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once the colleagues give a green light on all tests, the merge goes in and we can sit and wait for bugs for our new feature to roll in.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I hope you found something interesting in this post. On a related note, SAP HANA is &lt;a href=&quot;https://jobs.sap.com/search/?q=SAPhanacareers&amp;amp;locationsearch=&amp;amp;utm_source=DennisFelsing&quot;&gt;hiring right now in a few locations&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Discuss on &lt;a href=&quot;https://news.ycombinator.com/item?id=15890028&quot;&gt;Hacker News&lt;/a&gt; and &lt;a href=&quot;https://www.reddit.com/r/programming/comments/7if7fa/hana_c_development_environment_and_processes/&quot;&gt;r/programming&lt;/a&gt;.&lt;/p&gt;

   </content>
 </entry>
 
 <entry>
   <title>C++ Quiz #1</title>
   <link href="https://hookrace.net/blog/cpp-quiz-1/"/>
   <updated>2017-12-01T00:00:00-05:00</updated>
   <id>https://hookrace.net/blog/cpp-quiz-1</id>
   <content type="html">
     &lt;p&gt;What is the output of this small snippet that is based on real C++ code?&lt;/p&gt;

&lt;!--more--&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;iostream&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;standard&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;copy&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;int&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;int, int&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Foo, int&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;int, Foo&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;endl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Bar&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m_i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m_j&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Bar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The code compiles without warnings with clang++ 5.0.0 as well as g++ 7.2.0 using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-Wall -Wextra&lt;/code&gt;.&lt;/p&gt;

&lt;script language=&quot;javascript&quot;&gt;
function toggle() {
    var spoiler = document.getElementById(&quot;spoiler&quot;);
    spoiler.style.display = (spoiler.style.display == &quot;block&quot;) ? &quot;none&quot; : &quot;block&quot;;
}
&lt;/script&gt;

&lt;h2&gt;&lt;a href=&quot;javascript:toggle();&quot;&gt;Solution&lt;/a&gt;&lt;/h2&gt;

&lt;div id=&quot;spoiler&quot; style=&quot;display: none&quot;&gt;
  &lt;p&gt;The preliminaries are simple:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;We have a struct Foo with a few different constructors, each of which prints a text that represents its parameter types.&lt;/li&gt;
    &lt;li&gt;We have a struct Bar with two members, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_j&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main&lt;/code&gt; function calls the standard constructor of Bar.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;The constructor of Bar is where the magic happens, so let’s go through it line by line:&lt;/p&gt;

  &lt;ol&gt;
    &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(Foo(m_i, m_j))&lt;/code&gt; creates a temporary Foo object by calling the Foo constructor with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_j&lt;/code&gt; as parameters, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int, int&lt;/code&gt; is printed. The resulting Foo object is then passed to the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f(Foo(m_i))&lt;/code&gt; works analogously, it calls  the Foo constructor with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; as parameter, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int&lt;/code&gt; is printed. The resulting Foo object is then passed to the function &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;f&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo(m_i, m_j)&lt;/code&gt; works the same as the first line, except it doesn’t pass the resulting temporary Foo object to a function, so it is destroyed again immediately, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int, int&lt;/code&gt; is printed again.&lt;/li&gt;
    &lt;li&gt;So far so good, but now look closely. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo(m_i)&lt;/code&gt; surprisingly behaves entirely differently from all the previous lines. It does &lt;em&gt;not&lt;/em&gt; call the Foo constructor with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; as the parameter. Instead it creates a Foo object of the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt;, just like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo m_i&lt;/code&gt; would. So &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;standard&lt;/code&gt; is printed.&lt;/li&gt;
    &lt;li&gt;Now the last line looks just like the third line, but it still does something different. Why? Because the name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; is no longer referring to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;int m_i&lt;/code&gt; member of Bar. Instead &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m_i&lt;/code&gt; is now referring to a local variable of type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo&lt;/code&gt;, so &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo(m_i, m_j)&lt;/code&gt; prints &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Foo, int&lt;/code&gt;.&lt;/li&gt;
  &lt;/ol&gt;

  &lt;h2 id=&quot;explanation&quot;&gt;Explanation&lt;/h2&gt;

  &lt;p&gt;Thus spoke the C++ standard:&lt;/p&gt;

  &lt;blockquote&gt;
    &lt;p&gt;§8.3 Meaning of declarators&lt;/p&gt;

    &lt;p&gt;[…]&lt;/p&gt;

    &lt;p&gt;6 In a declaration &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T D&lt;/code&gt; where &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;D&lt;/code&gt; has the form&lt;/p&gt;

    &lt;p&gt;&lt;em&gt;( D1 )&lt;/em&gt;&lt;/p&gt;

    &lt;p&gt;the type of the contained &lt;em&gt;declarator-id&lt;/em&gt; is the same as that of the contained &lt;em&gt;declarator-id&lt;/em&gt; in the declaration&lt;/p&gt;

    &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;T D1&lt;/code&gt;&lt;/p&gt;

    &lt;p&gt;Parentheses do not alter the type of the embedded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;declarator-id&lt;/code&gt;, but they can alter the binding of complex declarators.&lt;/p&gt;
  &lt;/blockquote&gt;

  &lt;p&gt;This kind of ambiguous parsing can lead to dangerous situations, as is documented in &lt;a href=&quot;https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL53-CPP.+Do+not+write+syntactically+ambiguous+declarations&quot;&gt;DCL53-CPP&lt;/a&gt;:&lt;/p&gt;

  &lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-cpp&quot; data-lang=&quot;cpp&quot;&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;mutex&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mutex&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;shared_resource&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;increment_by_42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;unique_lock&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mutex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;shared_resource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;42&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

  &lt;p&gt;The code looks like it locks the mutex &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m&lt;/code&gt; while modifiying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;shared_resource&lt;/code&gt;, but instead a new mutex &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m&lt;/code&gt; is created, shadowing the global mutex &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;m&lt;/code&gt;.&lt;/p&gt;

  &lt;h2 id=&quot;future-directions&quot;&gt;Future Directions&lt;/h2&gt;

  &lt;p&gt;The upcoming Clang version will have a warning for this:&lt;/p&gt;

  &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;y.cpp:25:12: warning: parentheses were disambiguated as redundant parentheses around declaration of variable named
      &apos;m_i&apos; [-Wvexing-parse]
        Foo(m_i);
           ^~~~~
y.cpp:25:9: note: add enclosing parentheses to perform a function-style cast
        Foo(m_i);
        ^
        (       )
y.cpp:25:12: note: remove parentheses to silence this warning
        Foo(m_i);
           ^   ~
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;
&lt;/div&gt;

   </content>
 </entry>
 
</feed>
