<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C++ on Roberto Selbach</title><link>https://rselbach.com/tags/c++/</link><description>Recent content in C++ on Roberto Selbach</description><generator>Hugo</generator><language>en-US</language><lastBuildDate>Mon, 03 Jun 2002 07:54:19 +0000</lastBuildDate><atom:link href="https://rselbach.com/tags/c++/index.xml" rel="self" type="application/rss+xml"/><item><title>KParts Ownership in One Minute</title><link>https://rselbach.com/kparts-ownership-in-one-minute/</link><pubDate>Mon, 03 Jun 2002 07:54:19 +0000</pubDate><guid>https://rselbach.com/kparts-ownership-in-one-minute/</guid><description>&lt;p&gt;I embedded a viewer part, closed its window, and received a crash during shutdown. The viewer worked. My ownership did not.&lt;/p&gt;
&lt;p&gt;A &lt;code&gt;KPart&lt;/code&gt; is a &lt;code&gt;QObject&lt;/code&gt;, and its widget is usually parented into the host&amp;rsquo;s widget tree. Those are related lifetimes, but they are not an invitation to delete everything in sight. I now keep the part pointer in the host, give the constructor the intended object parent, and let that relationship determine destruction.&lt;/p&gt;
&lt;p&gt;The shape is roughly this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;KParts&lt;span style="color:#f92672"&gt;::&lt;/span&gt;ReadOnlyPart &lt;span style="color:#f92672"&gt;*&lt;/span&gt;part &lt;span style="color:#f92672"&gt;=&lt;/span&gt; factory&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;createPart(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parentWidget, &lt;span style="color:#e6db74"&gt;&amp;#34;viewer widget&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;this&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;viewer part&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;KParts::ReadOnlyPart&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;setCentralWidget(part&lt;span style="color:#f92672"&gt;-&amp;gt;&lt;/span&gt;widget());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The factory creates the component. The part owns its document behavior and supplies a widget for presentation. The shell owns the part through the &lt;code&gt;QObject&lt;/code&gt; parent passed to the factory. I do not separately delete the widget; its parent chain handles that.&lt;/p&gt;
&lt;p&gt;The other lifetime to remember is the component factory or library handle used to create the part. KDE&amp;rsquo;s loader machinery normally keeps the code available while objects from it exist. Bypassing that machinery and unloading a library while its C++ object remains is an efficient way to make a virtual call jump into empty space.&lt;/p&gt;
&lt;p&gt;My preference is one obvious owner and no emergency deletes in destructors. If I cannot explain who owns the part without drawing several arrows, I fix that before debugging anything else. The crash at exit is rarely impressed by a beautiful toolbar.&lt;/p&gt;</description></item><item><title>What moc Actually Generates</title><link>https://rselbach.com/what-moc-actually-generates/</link><pubDate>Thu, 07 Mar 2002 21:42:08 +0000</pubDate><guid>https://rselbach.com/what-moc-actually-generates/</guid><description>&lt;p&gt;I added a signal to a small Qt 3 class today, rebuilt, and received an undefined reference to the class&amp;rsquo;s virtual table. That message sounds like a C++ problem. In this case it meant I had forgotten about &lt;code&gt;moc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Qt&amp;rsquo;s signals and slots need information that the C++ compiler does not produce. A class using them declares &lt;code&gt;Q_OBJECT&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Counter&lt;/span&gt; &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; QObject
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Q_OBJECT
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Counter(QObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;parent &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;signals:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; changed(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; value);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; slots:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; setValue(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; value);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Meta Object Compiler reads that declaration and writes ordinary C++ containing the meta-object table and dispatch code. The generated file supplies, among other things, the pieces behind &lt;code&gt;className()&lt;/code&gt;, signal activation, and calls made through the string-based &lt;code&gt;connect()&lt;/code&gt; mechanism.&lt;/p&gt;
&lt;p&gt;In a KDE autotools project the build rules normally run &lt;code&gt;moc&lt;/code&gt; for headers containing &lt;code&gt;Q_OBJECT&lt;/code&gt;. If I put the class declaration in a &lt;code&gt;.cpp&lt;/code&gt; file, I include its generated output at the bottom:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-cpp" data-lang="cpp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34;counter.moc&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After adding or removing &lt;code&gt;Q_OBJECT&lt;/code&gt;, regenerating the build files is sometimes necessary. A clean rebuild is also cheaper than interpreting every vtable error as an omen.&lt;/p&gt;
&lt;p&gt;I like signals and slots because the sender does not need to know the receiver. The caveat is that the compiler cannot check the old &lt;code&gt;SIGNAL()&lt;/code&gt; and &lt;code&gt;SLOT()&lt;/code&gt; strings fully. A connection can compile and then complain at run time, so I watch the diagnostic output and keep signatures simple.&lt;/p&gt;</description></item><item><title>GCC 2.95 Is Part of the Platform</title><link>https://rselbach.com/gcc-295-is-part-of-the-platform/</link><pubDate>Mon, 18 Feb 2002 09:17:43 +0000</pubDate><guid>https://rselbach.com/gcc-295-is-part-of-the-platform/</guid><description>&lt;p&gt;I lost an afternoon to code that compiled perfectly on my machine and failed on the machine that actually had to ship it. Mine had a newer compiler. The other one had GCC 2.95, as do quite a few systems on which KDE software is expected to build.&lt;/p&gt;
&lt;p&gt;The useful lesson is not to argue with the compiler. It is to treat it as part of the target platform. If the project says it supports GCC 2.95, compile with GCC 2.95 before sending the change anywhere.&lt;/p&gt;
&lt;p&gt;I now keep a separate build tree for this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;mkdir build-gcc295
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;cd build-gcc295
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CC&lt;span style="color:#f92672"&gt;=&lt;/span&gt;gcc CXX&lt;span style="color:#f92672"&gt;=&lt;/span&gt;g++ ../configure --enable-debug
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;make
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The compiler is particularly good at finding ambitious template code. Partial specialization, dependent names, and clever overloads can all expose old parser bugs or incomplete language support. Usually the least surprising spelling wins: name types explicitly, keep templates small, and avoid making overload resolution solve a riddle.&lt;/p&gt;
&lt;p&gt;One more trap is mixing C++ libraries. An object compiled against an incompatible &lt;code&gt;libstdc++&lt;/code&gt; is not made safe merely because the linker accepted it. I build the whole program and its local libraries with the same toolchain.&lt;/p&gt;
&lt;p&gt;I would rather write plain code than maintain compiler-specific branches. It is less exciting, but so is a build finishing successfully, and I have learned to appreciate that particular lack of excitement.&lt;/p&gt;</description></item></channel></rss>