<div dir="ltr"><div dir="ltr">On Mon, Jun 8, 2020 at 8:20 PM Walter Bright 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/7/2020 11:14 PM, Manu wrote:<br>
> I think a first part of the conversation to understand, is that since D doesn't <br>
> really have first-class `inline` (just a pragma, assumed to be low-level <br>
> compiler control), I think most people bring their conceptual definition over <br>
> from C/C++, and that definition is a little odd (although it is immensely <br>
> useful), but it's not like what D does.<br>
<br>
C/C++ inline has always been a hint to the compiler, not a command.<br></blockquote><div><br></div><div>It's not a hint at all. It's a mechanical tool; it marks symbols with internal linkage, and it also doesn't emit them if it's never referenced.</div><div>The compiler may not choose to ignore that behaviour, it's absolutely necessary, and very important.</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 C/C++, inline says that a function will be emit to the binary only when it is <br>
> called, and the function is marked with internal linkage (it is not visible to <br>
> the linker from the symbol table)<br>
> By this definition; what inline REALLY means is that the function is not placed <br>
> in the binary where it is defined, it is placed in the binary where it is <br>
> CALLED, and each CU that calls an inline function receives their own copy of the <br>
> function.<br>
<br>
Why does it matter where it is emitted? Why would you want multiple copies of <br>
the same function in the binary?<br></blockquote><div><br></div><div>I want zero copies if it's never called. That's very important.</div><div>I also want copies to appear locally when it is referenced; inline functions should NOT require that you link something to get the code... that's not inline at all.</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">
> Another take on inline, and perhaps a more natural take (if your mind is not <br>
> poisoned by other native languages), is that the function is not actually emit <br>
> to an object anywhere, it is rather wired directly inline into the AST instead <br>
> of 'called'. Essentially a form of AST macro.<br>
<br>
The problem with this is what is inlined and what isn't is rather fluid, i.e. it <br>
varies depending on circumstances and which compiler you use. For example, if <br>
you recursively call a function, it's going to have to give up on inlining it. <br>
Changes in the compiler can expand or contract inlining opportunities. Having it <br>
inline or issue an error is disaster for compiling existing code without <br>
constantly breaking it.<br></blockquote><div><br></div><div>I understand why this particular take is more complicated; and as such I wouldn't suggest we do it. I'm just offering it as one possible take on the concept.</div><div>I think to make this form work, it must be handled in the frontend; essentially an AST macro. Naturally, it would fail on recursive calls, because that would be a recursive expansion.</div><div>I'm not suggesting we do this, except maybe what I describe as the #3 use case could potentially be this.</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">
> I reach for inline in C/C++ for various different reasons at different times, <br>
> and I'd like it if we were able to express each of them:<br>
> <br>
> 1. I only want the function to be present in the CALLING binary. I do not want <br>
> an inline function present in the local binary where it was defined (unless it <br>
> was called internally). I do not want a linker to see the inline function <br>
> symbols and be able to link to them externally. [This is about linkage and <br>
> controlling the binary or distribution environment]<br>
<br>
Why? What is the problem with the emission of one copy where it was defined?<br></blockquote><div><br></div><div>That's the antithesis of inline. If I wanted that, I wouldn't mark it inline.</div><div>I don't want a binary full of code that shouldn't be there. It's very important to be able to control what code is in your binaries.</div><div><br></div><div>If it's not referenced, it doesn't exist.</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">> 2. I am unhappy that the optimiser chose to not inline a function call, and I <br>
> want to override that judgement. [This is about micro-optimisation]<br>
<br>
It's not always possible to inline a function.<br></blockquote><div><br></div><div>Sure, but in this #2 case, I know it's possible, but the compiler chose not to. This #2 case is the 'hint' form.</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">
> 3. I want to treat the function like an AST macro; I want the function inserted <br>
> at the callsite, and I want to have total confidence in this mechanic. [This is <br>
> about articulate mechanical control over code-gen; ie, I know necessary facts <br>
> about the execution context/callstack that I expect to maintain]<br>
<br>
The PR I have on this makes it an informational warning. You can choose to be <br>
notified if inlining fails.<br></blockquote><div><br></div><div>That's not sufficient though for all use cases. This is a different kind of inline (I think it's 'force inline').</div><div>This #3 mechanic is rare, and #1/2 are overwhelmingly common. You don't want a sea of warnings to apply to cases of 1/2.</div><div>I think it's important to be able to distinguish #3 from the other 2 cases.</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">
> Are there non-theoretical use cases I've missed that people have encountered?<br>
<br>
At its root, inlining is an optimization, like deciding which variables go into <br>
registers.<br></blockquote><div><br></div><div>No, actually... it's not. It's not an 'optimisation' in any case except maaaaybe #2; it's about control of the binary output and code generation.</div><div>Low level control of code generation is important in native languages; that's why we're here.</div></div></div>