Friday, January 14, 2022

Digest for comp.lang.c++@googlegroups.com - 14 updates in 2 topics

Nikki Locke <nikki@trumphurst.com>: Jan 14 11:23PM

Available C++ Libraries FAQ
 
URL: http://www.trumphurst.com/cpplibs/
 
This is a searchable list of libraries and utilities (both free
and commercial) available to C++ programmers.
 
If you know of a library which is not in the list, why not fill
in the form at http://www.trumphurst.com/cpplibs/cppsub.php
 
Maintainer: Nikki Locke - if you wish to contact me, please use the form on the website.
Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 13 05:51PM -0800


> This causes a compilation warning with clang and when run prints out garbage
> as you'd expect if it were a non inline. However surely if the function is
> truly inline it should work.
 
Um... You are seriously confused. This is a rather widespread
misconception that keyword `inline` has something to do with "inlining"
function code at the call site.
 
1. "Declaring function as inline" and "embedding (inlining) function
code at a specific call site" are two completely different, independent,
unrelated things. In your example you simply declared a function as
`inline`, yet in your post you seem to be talking about embedding at a
specific call site. This makes no sense at all.
 
2. Keyword `inline` has absolutely nothing to do with embedding function
code at the call site. The purpose of `inline` keyword is to allow you
to defeat ODR restrictions for a function (or a variable) with external
linkage. By using `inline` you can provide multiple definitions of
functions (or variables) in your program and still not get those
"multiple definitions" complaints from the linker. That's the only thing
keyword `inline` does. That's what it is for.
 
3. Compiler decisions about embedding function code at a specific call
site is made independently at each call site. These decisions are not in
any way related to keyword `inline`. Even when a specific calls is
embedded, it still preserves the "normal" unembedded semantics of the
call. Local variables are destroyed at the same spot as they would be
destroyed in a normal call. You can't return references to automatic
variables from functions, period.
 
So, again, you seem to be mixing to completely unrelated matters. Don't
do this.
 
> Are locals for inlines temporaries created on the
> heap instead of being stored on the same stack as the calling function locals?
 
Strange question. Yes, they _are_ stored on the same stack. But why does
it matter? The language says that automatic variables are gone once the
function finishes working. That's all you need to know. Especially when
it comes to such non-trivial objects as `std::string`, whose lifetime is
not really limited by storage duration, but rather by
construction/destruction timeline.
 
--
Best regards,
Andrey Tarasevich
Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 13 07:30PM -0800

On 1/13/2022 2:08 AM, Bonita Montero wrote:
>> to do something special with that function signature. ...
 
> If you don't use link-time compiling the linker doesn't even see the
> inline-function.
 
Not true.
 
Whether the linker sees or doesn't see inline functions is unpredictable
(and therefore irrelevant). And inline function still has external
linkage, unless explicit steps are taken to give it internal linkage.
 
If the compiler decides to generate a regular body for an inline
function (e.g. because it decided to implement some call sites in this
TU as regular calls, because address of the function is taken, or simply
because it felt like it), the linker _will_ definitely see the generated
function body, just like for any other functions.
 
And this is actually the purpose of `inline` keyword: tell the linker
that if it encounters _multiple_ regular bodies of the same inline
function, it has to discard all but one of them (instead of complaining).
 
--
Best regards,
Andrey Tarasevich
Muttley@dastardlyhq.com: Jan 14 11:22AM

On Thu, 13 Jan 2022 17:51:45 -0800
 
>1. "Declaring function as inline" and "embedding (inlining) function
>code at a specific call site" are two completely different, independent,
>unrelated things. In your example you simply declared a function as
 
Wikipedia says otherwise:
 
https://en.wikipedia.org/wiki/Inline_function
 
"It serves as a compiler directive that suggests (but does not require) that
the compiler substitute the body of the function inline by performing inline
expansion, i.e. by inserting the function code at the address of each function
call,"
 
Perhaps you're the one who's getting confused?
"Öö Tiib" <ootiib@hot.ee>: Jan 14 04:02AM -0800

> expansion, i.e. by inserting the function code at the address of each function
> call,"
 
> Perhaps you're the one who's getting confused?
 
Wikipedia is (in kind of populist/politician manner) saying very same thing
that Andrey said. Read the Wikipedia article carefully (and as whole).
Does the sentence you quoted say that functions that you have declared
inline will be inlined, ever?
James Kuyper <jameskuyper@alumni.caltech.edu>: Jan 14 08:34AM -0500

> On Thu, 13 Jan 2022 17:51:45 -0800
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
...
> the compiler substitute the body of the function inline by performing inline
> expansion, i.e. by inserting the function code at the address of each function
> call,"
 
Wikipedia is a good source in general, and particularly for
computer-related stuff, but it isn't as authoritative as the C++
standard itself:
 
"... The inline specifier indicates to the implementation that inline
substitution of the function body at the point of call is to be
preferred to the usual function call mechanism. An implementation is not
required to perform this inline substitution at the point of call;
however, even if this inline substitution is omitted, the other rules
for inline functions specified in this subclause shall still be
respected. ..." (9.2.7p2)
 
Note that inline substitution, which he denies has anything to do with
the inline keyword, is in fact the primary thing that the description of
that keyword is concerned with. There's lots of other things that the
standard says about 'inline' in other sections of the standard, and it's
those other things that he's talking about, but all of those other
things are written merely to support the primary purpose of 'inline'.
There are other ways to get around the ODR rule that don't involve the
'inline' keyword.
 
> Perhaps you're the one who's getting confused?
 
He's not confused, he just doesn't approve of what the standard says
about "inline", and therefore deliberately misrepresents it. The
standard's wording above makes "inline" no more than a hint. An
implementation is free to perform inline substitution of any function
call, whether or not the function is declared 'inline', so long as the
result produces the same observable effects as calling a separate
function. Many implementations don't even implement 'inline' as a hint,
completely ignoring it when deciding whether or not to perform inline
substitution. That's why he pretends that the wording I've quoted above
doesn't exist.
 
The problem with your code is not that inline substitution isn't being
done (though that is a possibility), it's that you have incorrect
expectations about what the result of that substitution would be.
Whether inlined or not, the object named 's' is in a separate block from
the function call itself, and therefore has a lifetime that ends when
the end of that block is reached. Whether or not the function is
inlined, that occurs before your code uses the reference to 's'.
James Kuyper <jameskuyper@alumni.caltech.edu>: Jan 14 11:26AM -0500

On 1/14/22 8:34 AM, James Kuyper wrote:
...
> call, whether or not the function is declared 'inline', so long as the
> result produces the same observable effects as calling a separate
> function.
 
I wanted to point out that the opposite transformation is also
permitted: and implementation can take code out of the function where it
is written, and replace it with a call to a separate function created by
the implementation containing that code.
 
Why would an implementation do this? For the opposite of the reason it
would inline some code. In general, inlining trades off an increase in
the execution speed against increased code size. There are important
exceptions: the inlined code could be smaller than the code that would
needed to implement the function call. Even if it isn't, inline
substitution could open up opportunities for optimization involving
interactions between the code inside the inlined function, and code
surrounding the function call. However, when neither of those cases
apply, each call to a function that gets inlined increases the size of
the generated code.
 
When I first mentioned this possibility, I had no idea whether any
existing compiler would do this, but I thought it unlikely. I was
corresponding surprised by a response that identified a particular
compiler that actually did it. As I might have anticipated, that
compiler was cross-compiling for a memory-starved embedded system.
Unfortunately, that was a decade ago, and I no longer remember any details.
Manfred <invalid@invalid.add>: Jan 14 05:30PM +0100

On 1/14/2022 1:02 PM, Öö Tiib wrote:
> that Andrey said. Read the Wikipedia article carefully (and as whole).
> Does the sentence you quoted say that functions that you have declared
> inline will be inlined, ever?
 
Moreover, if someone wants to learn programming from Wikipedia, good
luck to them. But don't expect me to trust their code.
 
James Kuyper gave very clear explanations of the OP's mistake.
Muttley@dastardlyhq.com: Jan 14 04:40PM

On Fri, 14 Jan 2022 04:02:21 -0800 (PST)
>that Andrey said. Read the Wikipedia article carefully (and as whole).
>Does the sentence you quoted say that functions that you have declared
>inline will be inlined, ever?
 
What do you think "inserting the function code at the address of each
function call" means?
Andrey Tarasevich <andreytarasevich@hotmail.com>: Jan 14 08:43AM -0800

> expansion, i.e. by inserting the function code at the address of each function
> call,"
 
> Perhaps you're the one who's getting confused?
 
No, I'm not. The wording in point 1 on the Wikipedia page (as well as
the text of the standard) clearly states that in this role keyword
`inline` is just a suggestion. The language standard says that this
suggestion can be freely ignored by the compilers.
 
That is sufficient to completely discard point 1 from consideration. I
don't really know why the standard still keeps it as a _normative_ part
of the text, while the wording itself is completely _informative_ in its
essence. This state of affairs only helps to fuel the confusion.
 
--
 
As a historical note, it is true that keyword `inline` was originally
introduced specifically to "suggest" inlining of function bodies at call
sites. But it quickly became clear that it is useless and unnecessary in
this role. As a consequence, its role was refocused to being a "ODR
defeater" - a completely different purpose.
 
In a way, saying that `inline` suggests inlining is like saying that
"lvalue" refers to left-hand side of assignment. Yes, we all know that
historically this is how it came to existence. But we also know that
this is factually incorrect in the standard language.
 
--
Best regards,
Andrey Tarasevich
Muttley@dastardlyhq.com: Jan 14 04:49PM

On Fri, 14 Jan 2022 17:30:37 +0100
>> inline will be inlined, ever?
 
>Moreover, if someone wants to learn programming from Wikipedia, good
>luck to them. But don't expect me to trust their code.
 
Wikipedia tends to range from the uselessly sparse to the uselessly complex.
The article on discrete fourier transforms for example is pages of dense
mathematics probably written by post grad students or lecturers trying to
out-do each other in how obtuse they can be. I wrote an implementation in C
including comments that was 20 lines of code. Go figure.
David Brown <david.brown@hesbynett.no>: Jan 14 06:47PM +0100

On 14/01/2022 17:26, James Kuyper wrote:
> compiler that actually did it. As I might have anticipated, that
> compiler was cross-compiling for a memory-starved embedded system.
> Unfortunately, that was a decade ago, and I no longer remember any details.
 
If you are interested in such transformations, gcc does them (given the
right flags, appropriate code, and perhaps additional information such
as LTO, profile-guided optimisation or "hot" and "cold" function
attributes). In particular, it can pull out rarely used parts of code
into a separate function and re-use it from more than one place, or put
it in a different section to improve cache usage, or in connection with
function cloning and constant propagation. (Imagine a function that
takes a boolean parameter. In some cases, you get better results if you
have two versions of the function generated, each with a fixed value for
that parameter, and the choice of the function to use is made at the
call site.) Functions can also be partially inlined.
 
How often the compiler does such transformations, and how effective they
are in practice, I have no idea.
"Öö Tiib" <ootiib@hot.ee>: Jan 14 11:28AM -0800

> >inline will be inlined, ever?
> What do you think "inserting the function code at the address of each
> function call" means?
 
That means inlining. Does "suggests (but does not require) inlining" mean
that it will be inlined?
"Alf P. Steinbach" <alf.p.steinbach@gmail.com>: Jan 14 08:29PM +0100

> What do you think "inserting the function code at the address of each
> function call" means?
 
That's the thing that's not required, but can be done.
 
Which it also can without the `inline` keyword.
 
Originally `inline` did have a strong hinting effect about machine code
inlining. Bjarne wanted to do away with evil macros, as an advantage of
C++, and he wrote about that (somewhere, which I don't recall, but
probably tcpppl). However, things change, and among the changes was the
emergence of more compilers than just Bjarne's, and standardization, and
changes in common practice, and today the original intent of `inline` is
for all purposes a very very non-binding shallow hint, one that one
ideally could rely on /not/ being considered, because one wants the
guaranteed effect of `inline` without any silly side-effects.
 
- Alf
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: