<div dir="ltr"><div dir="ltr">On Fri, Jun 12, 2020 at 11:25 PM Andrei Alexandrescu via Digitalmars-d <<a href="mailto:digitalmars-d@puremagic.com">digitalmars-d@puremagic.com</a>> wrote:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 6/8/20 2:14 AM, Manu wrote:<br>
> In C/C++, inline says that a function will be emit to the binary only <br>
> when it is called, and the function is marked with internal linkage (it <br>
> is not visible to the linker from the symbol table)<br>
<br>
By my recollection this is not the case for C++, at all.<br>
<br>
* "inline" does NOT change a function's linkage in C++. You may have <br>
inline functions with internal linkage (static inline) or (default) <br>
external linkage. This is important because e.g. defining a static <br>
variable in an extern inline function will have the same address in all <br>
calls to the function.</blockquote><div><br></div><div>It absolutely changes the linkage.</div><div>I believe it uses what LLVM calls 'ChooseOne' in its code generator, I don't know about 'standard' linker terminology, if such a thing exists.</div><div><br></div><div>It's clearly in the spec too:</div><div>"""</div><ol style="line-height:1.5em;margin:0.3em 0px 0.5em 3.2em;padding:0px;color:rgb(0,0,0);font-family:DejaVuSans,"DejaVu Sans",arial,sans-serif;font-size:12.8px"><li style="margin-bottom:0.1em">There may be <a href="https://en.cppreference.com/w/cpp/language/definition#One_Definition_Rule" title="cpp/language/definition" style="text-decoration-line:none;color:rgb(11,0,128);background:none">more than one definition</a> of an inline function <span class="gmail-t-rev-inl gmail-t-since-cxx17" style="margin:0px;padding:0px;border:1px solid silver"><span style="margin:0px;padding:0px">or variable</span></span> in the program as long as each definition <b>appears in a different translation unit</b> and (for non-static inline functions <span class="gmail-t-rev-inl gmail-t-since-cxx17" style="margin:0px;padding:0px;border:1px solid silver"><span style="margin:0px;padding:0px">and variables</span></span>) all definitions are identical. For example, an inline function <span class="gmail-t-rev-inl gmail-t-since-cxx17" style="margin:0px;padding:0px;border:1px solid silver"><span style="margin:0px;padding:0px">or an inline variable</span></span> may be defined in a header file that is #include'd in multiple source files.</li></ol><div>"""</div><div><br></div><div>If not for that link flag, you receive a "multiply declared symbol" error.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
If the above is correct, a D language feature dedicated to inlining <br>
should do the following:<br>
<br>
* Always emit the function body in the .di file if ever asked to <br>
generate it.<br></blockquote><div><br></div><div>Your sentence is unclear, but I think we agree.</div><div>I like how I describe this better: "The function must be emit to the _calling_ CU"</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
* Never complain about duplicate symbols if an inline function has <br>
duplicate definitions.</blockquote><div><br></div><div>And as I have been saying: "It must have the appropriate linker flag" (again, I think LLVM calls it "ChooseOne")</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Then compilers can decide on specific inlining strategies using the <br>
language feature as a hint.<br></blockquote><div><br></div><div>Correct. Except in the case I described as case #3, in which it would be useful to have SOME WAY, to 'force inline' and receive an error if it failed.</div><div>I described this in case #3 like some sort of an AST inline; the inline is performed in the front-end as some sort of AST macro, then we can have complete confidence it happened, and error if not.</div><div>This is a DIFFERENT THING than 'inline' generally, and I would describe it as "force" inline, and suggested `pragma(inline, force)`.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
D does ALL of the above already for templates, so this is not a <br>
difficult feature to implement. In fact we use this technique (e.g. in <br>
druntime) by spelling inline as "()". Consider:<br>
<br>
int func(int) { ... body ... }<br>
<br>
Let's make this inline:<br>
<br>
int func()(int) { ... body ... }<br>
<br>
Done.<br></blockquote><div><br></div><div>Except for the sea of edge cases when you supply `func` to generic code that was expecting a function.</div><div>This is a sloppy and unsatisfying work-around.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
In D there's one additional implication of body availability - the <br>
function is eligible for CTFE. I think any adjustment to the extant <br>
inline pragma needs to make this a top-level consideration.<br></blockquote><div><br></div><div>I think this will work naturally with no changes today. If a function definition is present in a di file, you can CTFE call it, but (unless we fix inline) you can not call it at runtime (because no code will be emit anywhere).</div></div></div>