What does 'inline' mean?

Manu turkeyman at gmail.com
Sat Jun 13 01:13:19 UTC 2020


On Sat, Jun 13, 2020 at 10:20 AM Andrei Alexandrescu via Digitalmars-d <
digitalmars-d at puremagic.com> wrote:

> On 6/12/20 2:08 PM, Johan wrote:
> > On Friday, 12 June 2020 at 13:22:35 UTC, Andrei Alexandrescu wrote:
> >> On 6/8/20 2:14 AM, Manu wrote:
> >>> In C/C++, inline says that a function will be emit to the binary only
> >>> when it is called, and the function is marked with internal linkage
> >>> (it is not visible to the linker from the symbol table)
> >>
> >> By my recollection this is not the case for C++, at all.
> >>
> >> * "inline" does NOT change a function's linkage in C++. You may have
> >> inline functions with internal linkage (static inline) or (default)
> >> external linkage. This is important because e.g. defining a static
> >> variable in an extern inline function will have the same address in
> >> all calls to the function.
> >
> > I believe Manu tried to explain that `inline` in C++ really only affects
> > how the linker must treat the symbol, and it is best to remember that it
> > does nothing at all concerning "inlining" (putting function body inside
> > another).
>
> Thank you. That's not at all what he wrote. AT ALL. It's what I wrote.
>
> I'm emphasizing this because it has been a recurring problem: a
> legitimate problem with an explanation lost in translation.


You're joking right?
"""
1. *I only want the function to be present in the CALLING binary*. I do not
want an inline function present in the local binary where it was defined
(unless it was called internally). I do not want a linker to see the inline
function symbols and be able to link to them externally. [*This is about
linkage and controlling the binary or distribution environment*]
"""
There is absolutely nowhere in that text where I describe that a function
should be emit inline to the calling function. I couldn't possibly be
clearer about its placement into the calling CU.

I genuinely don't have any idea how I could have been misunderstood in this
thread. It seems most readers did not misunderstand me.

> `inline` is really a misnomer.
> > The "linkage" effect of `inline` is required for C++ to work with
> > #include files. There is some room for confusion because, depending on
> > who is talking, the word "linkage" can have more nuances than just
> > internal/external.
>
> It helps to use terminology that is well defined and standardized.
> That's where simply using the meaning defined and consistently used in
> the C++ standard document can be of great help.
>

We *are* using standard terminology. `inline` means something very specific
in C; it means deduplication of symbols, and that's what we're talking
about, for years.

> I personally take the broad stance of "linkage"
> > including anything the linker can do with the symbol.
>
> Makes sense. It's really nice to just use
> http://eel.is/c++draft/basic.link, which ensures we all understand one
> another.
>

There's no text in there that describes the link flags with standard
terminology. I have never heard standard terminology for them.
Can you show a reference for standard linker terminology which we can refer
to in the future?

LLVM is the only reference I know:
https://llvm.org/docs/LangRef.html#linkage-types

`internal` or `linkonce` are possible choices here, `linkonce` would match
C++.

> Without `inline`, you would get multiple definition linker errors for
> > functions defined in a header file when linking together two translation
> > units that both included that header file. Instead of normal function
> > linkage that forbids multiple definition, `inline` changes linkage to
> > merge multiple definitions into one.
>
> Not sure about that part - if linkage was static by means of using the
> "static" keyword, multiple definitions may not be merged. (I may be
> wrong, please correct me.) Consider:
>
> static inline int fun() {
>      static int x;
>      return ++x;
> }
>
> In C++, each translation unit containing a definition of fun() will have
> a distinct address for x. I don't see how the bodies of those functions
> can be merged.
>

`static inline` is strictly internal.
They will not be merged. Each CU will have its own copy of the function,
and it will not deduplicate.

We should be able use `private` the same way in D.

> In addition, emission of the function must happen in any translation
> > unit that references it (calling or address taken), and thus that
> > translation unit must also define it (in contrast to just declaring it).
> > I do not think `inline` forbids emission if the function is not
> referenced.
>
> I also think that's the case. (Also not what was claimed.)
>

This is literally point #1 in my OP... I honestly don't know how I could
have possibly been clearer about this. I've been saying it over and over
and over again for years.

The only difference you could perceive is that I suggest it should not emit
it if it's never referenced... to be clear; I was not commenting on what
C++ does, I was commenting on what I'd like.
It would be nice to not generate and emit the code and bloat the binary if
there are no calls. It's not necessary, because any external references
will have their own copy anyway.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20200613/9290c194/attachment-0001.htm>


More information about the Digitalmars-d mailing list