{"id":3655,"date":"2018-08-15T19:12:23","date_gmt":"2018-08-15T18:12:23","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3655"},"modified":"2018-08-15T19:12:23","modified_gmt":"2018-08-15T18:12:23","slug":"c-guns-why-c-ist-better-than-c-or-keyword-restrict-is-useless","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3655","title":{"rendered":"C++ Guns: why C++ ist better than C. Or: keyword restrict is useless"},"content":{"rendered":"<p>Das restricted keyword in C<\/p>\n<blockquote><p>restrict keyword...is basically a promise to the compiler that for the scope of the pointer, the target of the pointer will only be accessed through that pointer (and pointers copied from it).<\/p><\/blockquote>\n<p>In C++ geben wir keine Versprechen. Grunds\u00e4tzlich nicht.<br \/>\nDas Beispiel von cppreference.com verdeutlich das Optimierungspotential ziemlich anschaulich. Gegeben ist folgende Funktion:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nint foo(int &amp;a, int &amp;b) {\r\n    a = 5;\r\n    b = 6;\r\n    return a + b;\r\n}\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfoo(int&amp;, int&amp;):\r\n        movl    $5, (%rdi)     # store 5 in a\r\n        movl    $6, (%rsi)     # store 6 in b\r\n        movl    (%rdi), %eax   # read back from a in case previous store modified it\r\n        addl    $6, %eax       # add 6 to the value read from a\r\n        ret\r\n<\/pre>\n<p>Welche Optimierungsm\u00f6glichkeiten gibt es hier? Nat\u00fcrlich, der R\u00fcckgabewert ist 11 (5+6), solange die Referenzen von a und b auf unterschiedliche Variablen zeigen. Sonst ist der R\u00fcckgabewert 12 (6+6). Mit dem restrict keyword kann man l\u00fcgen und behaupten, dass die Referenzen von a und b nicht auf die selbe Variablen zeigen. Aber so etwas haben wir in C++ nicht n\u00f6tigt; der Compiler weiss es besser als wir.<br \/>\nJe nachdem in welchen Kontext die Funktion <em>foo<\/em> aufgerufen wird, kann optimiert werden, oder auch nicht. Beispielsweise ist in Funktion <em>func<\/em> zur Compilezeit sichergestellt, dass die Referenzen auf unterschiedliche Variablen zeigen. Entsprechend wird der R\u00fcckgabewert von 11 voraus berechnet und im Code abgelegt. <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto func(std::vector&lt;int&gt;&amp; arr, size_t i) {\r\n    return foo(arr&#x5B;i], arr&#x5B;i+1]);\r\n}\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfunc(std::vector&lt;int, std::allocator&lt;int&gt; &gt;&amp;, unsigned long):\r\n        movq    (%rdi), %rax\r\n        addq    $1, %rsi             # temp increment i\r\n        movl    $5, -4(%rax,%rsi,4)  # store 5 in a\r\n        movl    $6, (%rax,%rsi,4)    # store 6 in b\r\n        movl    $11, %eax            # the result is 11, a compile-time constant\r\n        ret\r\n<\/pre>\n<p>Zeigen die Referenzen hingegen auf die selbe Variable, wie in der Funktion <em>func2<\/em>, erkennt auch dies der Compiler und berechnet einen anderen R\u00fcckgabewert: 12. Auch in diesem Fall muss die Addition zur Laufzeit nicht ausgef\u00fchrt werden.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nauto func2(std::vector&lt;int&gt;&amp; arr, size_t i) {\r\n    return foo(arr&#x5B;i], arr&#x5B;i]);\r\n}\r\n<\/pre>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfunc2(std::vector&lt;int, std::allocator&lt;int&gt; &gt;&amp;, unsigned long):\r\n        movq    (%rdi), %rax\r\n        movl    $6, (%rax,%rsi,4)  # store 6 in a and b.\r\n        movl    $12, %eax          # the result is 12, a compile-time constant\r\n        ret\r\n<\/pre>\n<p>Fazit: Hinweise an den Compiler mit dem restrict keyword in C sind in C++ absolut \u00fcberfl\u00fcssig und f\u00fchren nur zu undefinierten Verhalten des Programms und damit zu schwer findbaren Bugs. Da die Debugzeit 1\/3 bis gerne 2\/3 der gesamten Entwicklungszeit ausmachen (in der Praxis, nicht in der Theorie), ist der Einsatz von C statt C++ unwirtschaftlich.<\/p>\n<p><a href=\"https:\/\/en.cppreference.com\/w\/c\/language\/restrict\">[1] https:\/\/en.cppreference.com\/w\/c\/language\/restrict<\/a><br \/>\n<a href=\"https:\/\/stackoverflow.com\/questions\/776283\/what-does-the-restrict-keyword-mean-in-c\">[2] https:\/\/stackoverflow.com\/questions\/776283\/what-does-the-restrict-keyword-mean-in-c<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das restricted keyword in C restrict keyword...is basically a promise to the compiler that for the scope of the pointer, the target of the pointer will only be accessed through that pointer (and pointers copied from it). In C++ geben wir keine Versprechen. Grunds\u00e4tzlich nicht. Das Beispiel von cppreference.com verdeutlich das Optimierungspotential ziemlich anschaulich. Gegeben [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[17],"class_list":["post-3655","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-cpp"],"_links":{"self":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3655","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3655"}],"version-history":[{"count":7,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3655\/revisions"}],"predecessor-version":[{"id":3662,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3655\/revisions\/3662"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3655"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3655"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3655"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}