Note that there are some explanatory texts on larger screens.

plurals
  1. POCode organization across files that has to deal with template functions and inlining
    primarykey
    data
    text
    <p>I'm maintaining a large library of template classes that perform algebraic computations based on either <code>float</code> or <code>double</code> type. Many of the classes have accessor methods (getters and setters) and other functions that run small amounts of code, therefore such functions need to be qualified as inline when the compiler locates their definitions. Other member functions, in contrast, contain sophisticated code and thus would better be called rather than inlined.</p> <p>A substantial part of the function definitions are located in headers, actually in .inl files included by headers. But there are also many classes whose function definitions happily live in .cpp files by means of explicit instantiation for <code>float</code> and <code>double</code>, which is rather a good thing to do in case of a library (<a href="https://stackoverflow.com/questions/2351148/explicit-instantiation">here</a> explained why). And finally, there is a considerable number of classes whose function definitions are broken across .inl files (accessor methods) and .cpp files (constructors, destructors, and heavy computations), which makes them all pretty difficult to maintain.</p> <p>I would have all my class implementations in .inl files only if I knew a reliable way to prevent some functions from being inlined, or in .cpp files if <code>inline</code> keyword could strongly suggest compiler to inline some of the functions, which, of course, it does not. I would really prefer all the function definitions in the library to reside in .cpp files, but since accessor methods are used extensively throughout the library, I have to make sure they are inlined whenever referenced, not called.</p> <p>So, in this connection, my questions are:</p> <ol> <li><p>Does it make any sense to mark the definition of a template function with <code>inline</code> in view of the fact that, as I've recently learnt <a href="https://stackoverflow.com/questions/11416747/multiple-definitions-of-a-non-template-class-vs-a-template-class">here</a>, it is going to be automatically qualified as inline by the compiler regardless of whether it's marked with <code>inline</code> or not?</p></li> <li><p>And <em>most importantly</em>, since I would like to have the definitions of all the member functions of a template class gathered <em>together in a single file</em>, either it's .inl or .cpp (using explicit instantiation in case of .cpp), preferably <em>still</em> being able to hint the compiler (MSVC and GCC) which of the functions should be inlined <em>and</em> which shouldn't, sure if such thing is possible with template functions, <em>how can I achieve this or,</em> if there is really no way (I hope there is), <em>what would be the most optimal compromise?</em></p></li> </ol> <h2>----------</h2> <p><em>EDIT1:</em> I knew that <code>inline</code> keyword is just a suggestion to the compiler to inline a function.</p> <p><em>EDIT2:</em> I really do know. I like making suggestions to the compiler.</p> <p><em>EDIT3:</em> I still know. It's not what the question is about.</p> <h2>----------</h2> <p><em>In view of some new information, there is also third question that goes hand in hand with the second one.</em></p> <p><em>3.</em> If compilers are so smart these days that they can make better choices about which function should be inlined and which should be called <em>and</em> are capable of link-time code generation and link-time optimization, which effectively allows them looking into a .cpp-located function definition at link time to decide its fate about being inlined or called, then maybe a good solution would be simply moving all the definitions into respective .cpp files?</p> <h2>----------</h2> <p><strong>So what's the conclusion?</strong></p> <p>First of all, I'm grateful to Daniel Trebbien and Jonathan Wakely for their structured and well-founded answers. Upvoted both but had to choose just one. None of the given answers, however, presented an acceptable solution to me, so the chosen answer happened to be the one that helped me slightly more than others in making the final decision, the details of which are explained next for anyone who's interested.</p> <p>Well, since I've always been valuing the performance of code more than how much convenient it is to maintain and develop, it appears to me that the most acceptable compromise would be to move all the accessor methods and other lightweight member functions of each of the template classes into the .inl file included by the respective header, marking these functions with <code>inline</code> keyword in an attempt to provide the compiler with a good hint (or with a keyword for inline forcing), and move the rest of the functions into the respective .cpp file.</p> <p>Having all member function definitions located in .cpp files would hinder inlining of lightweight functions while unleashing some problems with link-time optimization, as has been ascertained by Daniel Trebbien for MSVC (in an older stage of development) and by Jonathan Wakely for GCC (in its current stage of development). And having all function definitions located in headers (or .inl files) doesn't outweigh the summary benefit of having the implementation of each class sorted into .inl and .cpp files combined with a bonus side effect of this decision: it would ensure that only the code of primitive accessor methods is visible to a client of the library, while more juicy stuff is hidden in the binaries (ensuring this wasn't a major reason, however, but this plus was obvious for anyone who is familiar with software libraries). And any lightweight member function that doesn't need to be exposed by the include files of the library and is used privately by its class can have its definition in the .cpp file of the class, while its declaration/definition is spiced with <code>inline</code> to encourage the inline status of the function (don't know yet whether the keyword should be in both places or just one in this particular case).</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload