{"id":3486,"date":"2018-05-15T19:26:46","date_gmt":"2018-05-15T18:26:46","guid":{"rendered":"http:\/\/roboblog.fatal-fury.de\/?p=3486"},"modified":"2018-05-15T19:26:46","modified_gmt":"2018-05-15T18:26:46","slug":"c-guns-use-templates-and-inline-dont-use-libraries","status":"publish","type":"post","link":"http:\/\/roboblog.fatal-fury.de\/?p=3486","title":{"rendered":"C++ Guns: use templates and inline; don't use libraries"},"content":{"rendered":"<p>Der Compiler kann wirklich ganz viel Optimieren, solange er das komplette Programm als Code sehen kann. Wird irgendwo eine Funktion aus einer Laufzeit-Bibliothek aufgerufen, ist es vorbei mit der Optimierung. Ein kleines Beispiel soll das verdeutlichen:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid foo(const int &amp;x); \r\n\r\nint bar() {\r\n    int x = 0;\r\n    int y = 0;\r\n    for (int i = 0; i &lt; 10; i++) {\r\n        foo(x);\r\n        y += x;\r\n    }\r\n    return y;\r\n}\r\n<\/pre>\n<p>Die Funktion foo ist nicht definiert, das g\u00e4be einen Linker Error. Wichtig ist erst einmal, dass zur Compilezeit nicht bekannt ist, was die funktion foo tut. Dementsprechend k\u00f6nnen keine Annahmen getroffen werden um weitere Optimierungen vorzunehmen. Die Assembercode sieht aus wie erwartet:<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nbar():\r\n  pushq %rbp           \/\/ safe register rbp rbx\r\n  pushq %rbx\r\n  subq $24, %rsp       \/\/ allocate memory on stack\r\n  movl $0, 12(%rsp)    \/\/ x=0\r\n  movl $10, %ebx       \/\/ i=10 \r\n  movl $0, %ebp        \/\/ y=0\r\n.L2:                   \/\/ for...\r\n  leaq 12(%rsp), %rdi\r\n  call foo(int const&amp;)\r\n  addl 12(%rsp), %ebp  \/\/ y += x\r\n  subl $1, %ebx        \/\/ --i\r\n  jne .L2\r\n  movl %ebp, %eax     \/\/ return y\r\n  addq $24, %rsp      \/\/ release memory on stack\r\n  popq %rbx           \/\/ restore register\r\n  popq %rbp\r\n  ret\r\n<\/pre>\n<p>Der C++ Code wurde quasi 1:1 in Assember umgesetzt. Nichts besonderes.<br \/>\nWenn jetzt die Funktion bar() bekannt ist und zum Beispiel einfach eine leere Funktion ist, \u00e4ndern die etwas am erzeugten Assembler Code? Allerdings!<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nfoo(int const&amp;):\r\n  ret\r\nbar():\r\n  movl $0, %eax\r\n  ret\r\n<\/pre>\n<p>Der Compiler hat quasi alles weg-optimiert. Der Funktionsaufruf von foo(), die Addition von y, die Schleife. Das sichern der Register ist nicht mehr notwenig. Stack Speicher wird nicht genutzt. Der Compiler hat erkannt, dass die Funktion immer 0 zur\u00fcck gibt. <\/p>\n<p>Also: benutzt templates und inline, statt klassische Bibliotheks-Funktions-Aufrufe.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Der Compiler kann wirklich ganz viel Optimieren, solange er das komplette Programm als Code sehen kann. Wird irgendwo eine Funktion aus einer Laufzeit-Bibliothek aufgerufen, ist es vorbei mit der Optimierung. Ein kleines Beispiel soll das verdeutlichen: void foo(const int &amp;x); int bar() { int x = 0; int y = 0; for (int i = [&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-3486","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\/3486","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=3486"}],"version-history":[{"count":1,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3486\/revisions"}],"predecessor-version":[{"id":3487,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=\/wp\/v2\/posts\/3486\/revisions\/3487"}],"wp:attachment":[{"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3486"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3486"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/roboblog.fatal-fury.de\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3486"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}