{"id":5761,"date":"2019-08-22T16:17:08","date_gmt":"2019-08-22T16:17:08","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/further-myths-from-my-readers\/"},"modified":"2019-08-22T16:17:08","modified_gmt":"2019-08-22T16:17:08","slug":"further-myths-from-my-readers","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/further-myths-from-my-readers\/","title":{"rendered":"Myths of My Blog Readers"},"content":{"rendered":"<p>I was inquisitive about your C++ myths. In particular, my German readers were quite active. I got a few E-Mails and observed a vivid discussion on <a href=\"https:\/\/www.heise.de\/forum\/heise-Developer\/Kommentare\/C-Core-Guidelines-Mehr-Nichtregeln-und-Mythen\/forum-432200\/comment\/\">Heise Developer<\/a>.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5760\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/08\/dragon-1512457_1280.png\" alt=\"dragon 1512457 1280\" width=\"600\" height=\"338\" style=\"display: block; margin-left: auto; margin-right: auto;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/08\/dragon-1512457_1280.png 1280w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/08\/dragon-1512457_1280-300x169.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/08\/dragon-1512457_1280-1024x576.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2019\/08\/dragon-1512457_1280-768x432.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<p>Let me first conclude the myths of the C++ core guidelines before I write about your myths. Here is the last myth.<\/p>\n<h2><a href=\"http:\/\/isocpp.github.io\/CppCoreGuidelines\/CppCoreGuidelines#Rnr-protected-data\">NR.7: Don\u2019t: Make all data members <code class=\"highlighter-rouge no-highlight\">protected<\/code><\/a><\/h2>\n<p>Protected data makes your program complex and error-prone. If you put protected data into a base class, you can not reason about derived classes in isolation and, therefore, you break encapsulation. You always have to reason about the entire class hierarchy.<\/p>\n<p>This means you have to answer at least these three questions.<\/p>\n<ol>\n<li>Do I have to implement a constructor in a derived class to initialize the protected data?<\/li>\n<li>What is the actual value of the protected data if I use them?<\/li>\n<li>Who will be affected if I modify the protected data?<\/li>\n<\/ol>\n<p>Answering these questions becomes more and more complicated the deeper your class hierarchy becomes.<\/p>\n<p>If you think about it: protected data is a kind of global data in the scope of the class hierarchy. And you know, a mutable shared state is terrible. It makes, for example, testing and concurrency quite tricky.<\/p>\n<p>Now, I switch to your myths. I write about them in the order I received them.<\/p>\n<\/p>\n<h2>In C++ written programs need more memory and CPU as in C written programs (Gunter K\u00f6nigsmann)<\/h2>\n<p>First of all: thanks to Gunter K\u00f6nigsmann for the classical myth.<\/p>\n<p>Arguing against this myth is tricky and, in general, impossible for the C++ standard library. This is why I make only a few observations at the end of this chapter. First of all, here are the hard facts. The &#8220;Technical Report on C++ Performance&#8221; helps me a lot.<\/p>\n<h3 id=\"h1-technical-report-on-c-performance\"><a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/TR18015.pdf\">Technical report on C++ performance<\/a><\/h3>\n<p>The Working Group WG 21 published in the year 2006 the paper <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/TR18015.pdf\">ISO\/IEC TR 18015<\/a>. The title sounds not very interesting, but that document is the ultimate source if you want to get the performance numbers of the C++ features. The document expresses its concerns directly to the point.&nbsp;&nbsp;<\/p>\n<ul>\n<li><em>to give the reader a model of time and space overheads implied by the use of various C++ language and library features,<\/em><\/li>\n<li><em>to debunk widespread myths about performance problems,<\/em><\/li>\n<li><em>to present techniques for the use of C++ in applications where performance matters, and<\/em><\/li>\n<li><em>to present techniques for implementing C++ Standard language and library facilities to yield efficient code.<\/em><\/li>\n<\/ul>\n<p>With more than 200 pages, the paper&#8217;s authors are well-known C++ experts like&nbsp;Dave Abrahams, Howard Hinnand, Dietmar K\u00fchl, Dan Saks, Bill Seymour, Bjarne Stroustrup, and Detlef Vollmann.<\/p>\n<p>The scope of the document is C++ features, their overhead and usage, the creation of efficient libraries in C++, the usage of C++ in embedded systems, and the interfaces in C++ to communicate with the hardware.<\/p>\n<h3 id=\"h1-1-c-features-overhead-and-usage\">C++ features, Overhead, and Usage<\/h3>\n<p>The authors use for their analysis three computer architectures with five different compilers. They use compilers with different optimization levels. I will give you only an idea of the results that are pretty remarkable.<\/p>\n<ul>\n<li>Namespaces\n<ul>\n<li>Have no significant overhead in size and performance<\/li>\n<\/ul>\n<\/li>\n<li>Type converting operator\n<ul>\n<li>The C++ casts <span style=\"font-family: courier new, courier;\">const_cast, static_cast, <\/span>and <span style=\"font-family: courier new, courier;\">reinterpret_cast<\/span> differ neither in size nor performance from their C pedant.<\/li>\n<li>The runtime executed <span style=\"font-family: courier new, courier;\">dynamic_cast<\/span> has some overhead<em><\/em>. (Remark: The conversion has no C pendant.).<\/li>\n<\/ul>\n<\/li>\n<li>Inheritance\n<ul>\n<li>Class\n<ul>\n<li>A <span style=\"font-family: courier new, courier;\">class<\/span> without virtual functions is as big as a <span style=\"font-family: courier new, courier;\">struct<\/span>.<\/li>\n<li>A class with virtual functions has the overhead of a pointer and a virtual function table. These are about 2 to 4 bytes.&nbsp;<\/li>\n<\/ul>\n<\/li>\n<li>Function calls\n<ul>\n<li>The call of a non-virtual, non-static, and non-inline function is as expensive as the call of a free function.<\/li>\n<li>The call of a virtual function is as expensive as a free function with the help of a pointer stored in a table.&nbsp;<\/li>\n<li>Virtual functions of a class template can cause overhead in size.<\/li>\n<li>The <em>inlining <\/em>of a function causes significant performance benefits and is close to the performance of a C macro.<\/li>\n<\/ul>\n<\/li>\n<li>Multiple inheritances\n<ul>\n<li>It can cause time and space overhead.<\/li>\n<li>Virtual base classes have overhead compared to non-virtual base classes.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Run-time type&nbsp;information (RTTI)\n<ul>\n<li>There are about 40 additional bytes for each class necessary.<\/li>\n<li>The <span style=\"font-family: courier new, courier;\">typeid<\/span> call is relatively slow. That seems to be due to the quality of the implementation.<\/li>\n<li>The conversion during runtime with <span style=\"font-family: courier new, courier;\">dynamic_cast<\/span> is slow, according to the reports. That should also be due to the quality of the implementation.<\/li>\n<\/ul>\n<\/li>\n<li>Exception handling\n<ul>\n<li>There are two strategies for dealing with exceptions. These are the code and the table strategy. The code strategy must move and manage additional data structures to deal with exceptions. The table strategy has the execution context in a table.&nbsp;\n<ul>\n<li>The&nbsp;<em><\/em>code strategy has a size overhead for the stack and the runtime. The runtime overhead is about 6%. This overhead exists even without the throwing of an exception.<\/li>\n<li><em><\/em>The table strategy has neither overhand in program size nor runtime. (Remarks: That statements hold only if no exceptions were thrown.). The table strategy is more challenging to implement.&nbsp;<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>Templates\n<ul>\n<li>You get for each template instantiation a new class template or function template. Therefore, the naive use of temples can cause code bloat. Modern C++ compilers can massively reduce the number of template instantiations. The usage of partial or full specialization helps to reduce template instantiations.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>You can read the details, the exact number, and a few additional topics directly in the report: <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/TR18015.pdf\">TR18015.pdf.<\/a><\/p>\n<p>Still not convinced? Here is a citation from MISRA C++:<\/p>\n<h3><a href=\"http:\/\/www.misra.org.uk\/Activities\/tabid\/56\/Default.aspx\">MISRA C++<\/a><\/h3>\n<p>MISRA C++ (<strong>M<\/strong>otor <strong>I<\/strong>ndustry <strong>S<\/strong>oftware <strong>R<\/strong>eliability <strong>A<\/strong>ssociation) formulates guidelines for software in safety-critical systems.&nbsp; Initially designed for the automotive industry, it became the de facto standard in the aviation, military, and medical sectors. The question is, what MISRA says about C++?<\/p>\n<p>MISRA emphasizes why the importance of C++ in critical systems becomes more important. (1.1 The use of C++ in critical systems):<\/p>\n<ul>\n<li><em>C++ gives good support for high-speed, low-level, input\/output operations, which are essential to many embedded systems.<\/em><\/li>\n<li><em>The increased complexity of applications makes the use of a high-level language more appropriate than assembly language.<\/em><\/li>\n<li><em>C++ compilers generate code with similar size and RAM requirements to those of C.<\/em><\/li>\n<\/ul>\n<p>But one slight downer remains. MISRA C++ is based on classical C++. This is simply speaking C++98. Modern C++ has a lot more to offer for embedded systems. This remark holds not only for MISRA C++ but also for the previously mentioned <a href=\"http:\/\/www.open-std.org\/jtc1\/sc22\/wg21\/docs\/TR18015.pdf\">Technical report on C++ performance.<\/a><\/p>\n<p>I can not conclude my post without a few observations of modern C++.&nbsp; Modern C++ is primarily used for the three C++ standards&nbsp; C++11, C++14, and C++17.<\/p>\n<h3>My Observations<\/h3>\n<p>The difficulty in the comparison of the C++ standard library to its C pendants is, in particular, that you have to compare equivalent data structures or programs. This means you can not compare a C-string and a C++ string because the latter supports automatic memory management. The same holds for a C-array in contrast to the C++ containers. Without further ado, here are my points. If you are more curious, read the mentioned post.<\/p>\n<ul>\n<li>A<span style=\"font-family: courier new, courier;\"> std::array<\/span> is per design as fast and as cheap as a C-array and additionally knows its length: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-std-array-and-std-vector-are-your-friends\">C++ Core Guidelines: std::array and std::vector are your Friends.<\/a><\/li>\n<li>A<span style=\"font-family: courier new, courier;\"> std::unique_ptr<\/span> is, per design, as fast and as cheap as a raw pointer. Of course, the <span style=\"font-family: courier new, courier;\">std::unique_ptr<\/span> is safe per design: <a href=\"https:\/\/www.modernescpp.com\/index.php\/memory-and-performance-overhead-of-smart-pointer\">Memory and Performance Overhead of Smart Pointers<\/a>.<\/li>\n<li>&nbsp;The type-traits library allows it to write code that optimizes itself: <a href=\"https:\/\/www.modernescpp.com\/index.php\/type-traits-performance-matters\">Type-Traits: Performance matters<\/a>.<\/li>\n<li>With <span style=\"font-family: courier new, courier;\">constexpr<\/span>, you can perform expensive compute jobs at compile-time: <a href=\"https:\/\/www.modernescpp.com\/index.php\/c-core-guidelines-programming-at-compile-time-with-constexpr\">C++ Core Guidelines: Programming at Compile Time with constexpr<\/a>.<\/li>\n<li>Move-semantic and perfect forwarding allows you to replace an expensive and insecure copy operation with a cheap and secure move operation. Generally, a copy operation can fail instead of a move operation:<a href=\"https:\/\/www.modernescpp.com\/index.php\/copy-versus-move-semantic-a-few-numbers\">&nbsp;Copy versus Move Semantic: A few Numbers<\/a> and<a href=\"https:\/\/www.modernescpp.com\/index.php\/perfect-forwarding\"> Perfect Forwarding<\/a>.<\/li>\n<\/ul>\n<h2>What&#8217;s next?<\/h2>\n<p>Wow? Arguing against the memory and performance myth took almost an entire post. You can imagine that I have to demystify additional myths which I got. If you have a myth, it&#8217;s time to send it to me: <span id=\"cloak16b8d85e1f1952dfd67432c384344528\"><a href=\"mailto:rainer.grimm@modernescpp.de\">rainer.grimm@modernescpp.de<\/a><\/span>.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was inquisitive about your C++ myths. In particular, my German readers were quite active. I got a few E-Mails and observed a vivid discussion on Heise Developer.<\/p>\n","protected":false},"author":21,"featured_media":5760,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[372],"tags":[],"class_list":["post-5761","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-modern-c"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5761","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5761"}],"version-history":[{"count":0,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5761\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5760"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5761"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5761"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5761"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}