Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #82759 > unrolled thread

Inline functions and locals

Started byMuttley@dastardlyhq.com
First post2022-01-12 16:34 +0000
Last post2022-01-18 09:20 +0100
Articles 20 on this page of 47 — 13 participants

Back to article view | Back to comp.lang.c++


Contents

  Inline functions and locals Muttley@dastardlyhq.com - 2022-01-12 16:34 +0000
    Re: Inline functions and locals Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-12 17:38 +0100
    Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-12 12:47 -0500
    Re: Inline functions and locals Juha Nieminen <nospam@thanks.invalid> - 2022-01-13 07:00 +0000
      Re: Inline functions and locals "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-01-13 10:45 +0100
        Re: Inline functions and locals Juha Nieminen <nospam@thanks.invalid> - 2022-01-17 12:55 +0000
          Re: Inline functions and locals David Brown <david.brown@hesbynett.no> - 2022-01-17 15:14 +0100
          Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-17 10:24 -0800
            Re: Inline functions and locals David Brown <david.brown@hesbynett.no> - 2022-01-17 19:46 +0100
      Re: Inline functions and locals Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-13 11:08 +0100
        Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-13 19:30 -0800
    Re: Inline functions and locals Paavo Helde <eesnimi@osa.pri.ee> - 2022-01-13 12:46 +0200
      Re: Inline functions and locals Muttley@dastardlyhq.com - 2022-01-13 15:38 +0000
    Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-13 17:51 -0800
      Re: Inline functions and locals Muttley@dastardlyhq.com - 2022-01-14 11:22 +0000
        Re: Inline functions and locals Öö Tiib <ootiib@hot.ee> - 2022-01-14 04:02 -0800
          Re: Inline functions and locals Manfred <invalid@invalid.add> - 2022-01-14 17:30 +0100
            Re: Inline functions and locals Muttley@dastardlyhq.com - 2022-01-14 16:49 +0000
          Re: Inline functions and locals Muttley@dastardlyhq.com - 2022-01-14 16:40 +0000
            Re: Inline functions and locals Öö Tiib <ootiib@hot.ee> - 2022-01-14 11:28 -0800
            Re: Inline functions and locals "Alf P. Steinbach" <alf.p.steinbach@gmail.com> - 2022-01-14 20:29 +0100
        Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-14 08:34 -0500
          Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-14 11:26 -0500
            Re: Inline functions and locals David Brown <david.brown@hesbynett.no> - 2022-01-14 18:47 +0100
        Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-14 08:43 -0800
          Re: Inline functions and locals Juha Nieminen <nospam@thanks.invalid> - 2022-01-17 05:38 +0000
            Re: Inline functions and locals David Brown <david.brown@hesbynett.no> - 2022-01-17 08:12 +0100
              Re: Inline functions and locals "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-01-16 23:51 -0800
                Re: Inline functions and locals "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2022-01-16 23:55 -0800
                Re: Inline functions and locals David Brown <david.brown@hesbynett.no> - 2022-01-17 11:35 +0100
              Re: Inline functions and locals Juha Nieminen <nospam@thanks.invalid> - 2022-01-17 09:50 +0000
                Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-17 14:39 -0500
                  Re: Inline functions and locals Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-17 15:34 -0800
                    Re: Inline functions and locals "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-01-17 15:50 -0800
                      Re: Inline functions and locals Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-04-25 03:42 -0700
                        Re: Inline functions and locals "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> - 2022-04-25 08:48 -0700
            Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-16 23:53 -0800
              Re: Inline functions and locals Tim Rentsch <tr.17687@z991.linuxsc.com> - 2022-01-17 15:29 -0800
      Re: Inline functions and locals Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-17 12:40 +0100
        Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-17 10:13 -0800
          Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-17 16:15 -0500
            Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-17 16:28 -0800
              Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-17 22:55 -0500
                Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-18 11:32 -0800
                  Re: Inline functions and locals James Kuyper <jameskuyper@alumni.caltech.edu> - 2022-01-18 19:03 -0500
                    Re: Inline functions and locals Andrey Tarasevich <andreytarasevich@hotmail.com> - 2022-01-18 17:22 -0800
          Re: Inline functions and locals Bonita Montero <Bonita.Montero@gmail.com> - 2022-01-18 09:20 +0100

Page 2 of 3 — ← Prev page 1 [2] 3  Next page →


#82781

From"Alf P. Steinbach" <alf.p.steinbach@gmail.com>
Date2022-01-14 20:29 +0100
Message-ID<srsive$2vg$1@dont-email.me>
In reply to#82776
On 14 Jan 2022 17:40, Muttley@dastardlyhq.com wrote:
> 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

[toc] | [prev] | [next] | [standalone]


#82773

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-01-14 08:34 -0500
Message-ID<srru5t$939$1@dont-email.me>
In reply to#82771
On 1/14/22 6:22 AM, Muttley@dastardlyhq.com wrote:
> On Thu, 13 Jan 2022 17:51:45 -0800
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
...
>> 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 
> 
> 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,"

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'.

[toc] | [prev] | [next] | [standalone]


#82774

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-01-14 11:26 -0500
Message-ID<srs873$ijn$1@dont-email.me>
In reply to#82773
On 1/14/22 8:34 AM, James Kuyper wrote:
...
> 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.

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.

[toc] | [prev] | [next] | [standalone]


#82779

FromDavid Brown <david.brown@hesbynett.no>
Date2022-01-14 18:47 +0100
Message-ID<srsd0a$o56$1@dont-email.me>
In reply to#82774
On 14/01/2022 17:26, James Kuyper wrote:
> On 1/14/22 8:34 AM, James Kuyper wrote:
> ...
>> 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.
> 
> 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.
> 

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.

[toc] | [prev] | [next] | [standalone]


#82777

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2022-01-14 08:43 -0800
Message-ID<srs97q$qov$1@dont-email.me>
In reply to#82771
On 1/14/2022 3:22 AM, Muttley@dastardlyhq.com wrote:
> On Thu, 13 Jan 2022 17:51:45 -0800
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>> On 1/12/2022 8:34 AM, Muttley@dastardlyhq.com wrote:
>>> I'm curious as to why returning a reference to a local inside an inline
>>> function isn't (apparently) allowed. eg:
>>>
>>> #include <iostream>
>>> #include <string>
>>>
>>> using namespace std;
>>>
>>> inline string &func()
>>> {
>>>           string s = "hello";
>>>           return s;
>>> }
>>>
>>>
>>>
>>> int main()
>>> {
>>>           cout << func() << endl;
>>>           return 0;
>>> }
>>>
>>> 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
> 
> 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?
> 

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

[toc] | [prev] | [next] | [standalone]


#82789

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-01-17 05:38 +0000
Message-ID<ss2vdc$eo5$1@gioia.aioe.org>
In reply to#82777
Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
> 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.

And as a side note, the C standard also added support for 'inline'
functions, except that it's a different and very weird version of it that
to this day I still don't fully understand. It's like an 'inline' that's
*not* an "ODR defeater". (It's so confusing that the vast, vast majority
of C programmers just write "static inline" to get around the confusing
part.)

[toc] | [prev] | [next] | [standalone]


#82790

FromDavid Brown <david.brown@hesbynett.no>
Date2022-01-17 08:12 +0100
Message-ID<ss34s6$53h$1@dont-email.me>
In reply to#82789
On 17/01/2022 06:38, Juha Nieminen wrote:
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>> 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.
> 
> And as a side note, the C standard also added support for 'inline'
> functions, except that it's a different and very weird version of it that
> to this day I still don't fully understand. It's like an 'inline' that's
> *not* an "ODR defeater". (It's so confusing that the vast, vast majority
> of C programmers just write "static inline" to get around the confusing
> part.)
> 

Yes, "inline" functions in C are a bit odd, and the semantics are not
the same as in C++.  As you say, the most common usage (and the only way
I use it) is to write "static inline" for functions to replace what
might pre-C99 have been a function-like macro.  The "inline" here is not
actually very significant - any decent C compiler will make its own
decisions about actual inlining optimisations, so a plain "static"
function would have the same effect.  To me, at least, the "static
inline" is a documentation of how you see the function and expect it to
be used.

<https://en.cppreference.com/w/c/language/inline>

To add to the complication, gcc had "inline" as an extension prior to
C99, and it had slightly different semantics.  (A number of gcc C89
extensions became part of C99, sometimes with changes.)  For "static
inline" functions there is no difference, but there are differences for
"extern inline" and other combinations.  This reinforces the benefits of
sticking to "static inline" in C.

<https://gcc.gnu.org/onlinedocs/gcc/Inline.html>

[toc] | [prev] | [next] | [standalone]


#82791

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2022-01-16 23:51 -0800
Message-ID<ss375r$gjs$1@dont-email.me>
In reply to#82790
On 1/16/2022 11:12 PM, David Brown wrote:
> On 17/01/2022 06:38, Juha Nieminen wrote:
>> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>>> 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.
>>
>> And as a side note, the C standard also added support for 'inline'
>> functions, except that it's a different and very weird version of it that
>> to this day I still don't fully understand. It's like an 'inline' that's
>> *not* an "ODR defeater". (It's so confusing that the vast, vast majority
>> of C programmers just write "static inline" to get around the confusing
>> part.)
>>
> 
> Yes, "inline" functions in C are a bit odd, and the semantics are not
> the same as in C++.  As you say, the most common usage (and the only way
> I use it) is to write "static inline" for functions to replace what
> might pre-C99 have been a function-like macro.  The "inline" here is not
> actually very significant - any decent C compiler will make its own
> decisions about actual inlining optimisations, so a plain "static"
> function would have the same effect.  To me, at least, the "static
> inline" is a documentation of how you see the function and expect it to
> be used.
[...]

Imvvvho, using inline is almost akin to almost begging the compiler to 
actually inline the function. It certainly can say f-you, and give the 
programmer the proverbial middle finger at the same time! For some 
reason it kind of makes me think of the register keyword...

Now, it would be funny if a compiler would output something like:

this function cannot be inlined, go ahead and try turning on link time 
optimization, and try again? ;^)

[toc] | [prev] | [next] | [standalone]


#82793

From"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>
Date2022-01-16 23:55 -0800
Message-ID<ss37dl$jqi$1@dont-email.me>
In reply to#82791
On 1/16/2022 11:51 PM, Chris M. Thomasson wrote:
> On 1/16/2022 11:12 PM, David Brown wrote:
>> On 17/01/2022 06:38, Juha Nieminen wrote:
>>> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>>>> 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.
>>>
>>> And as a side note, the C standard also added support for 'inline'
>>> functions, except that it's a different and very weird version of it 
>>> that
>>> to this day I still don't fully understand. It's like an 'inline' that's
>>> *not* an "ODR defeater". (It's so confusing that the vast, vast majority
>>> of C programmers just write "static inline" to get around the confusing
>>> part.)
>>>
>>
>> Yes, "inline" functions in C are a bit odd, and the semantics are not
>> the same as in C++.  As you say, the most common usage (and the only way
>> I use it) is to write "static inline" for functions to replace what
>> might pre-C99 have been a function-like macro.  The "inline" here is not
>> actually very significant - any decent C compiler will make its own
>> decisions about actual inlining optimisations, so a plain "static"
>> function would have the same effect.  To me, at least, the "static
>> inline" is a documentation of how you see the function and expect it to
>> be used.
> [...]
> 
> Imvvvho, using inline is almost akin to almost begging the compiler to 
> actually inline the function. It certainly can say f-you, and give the 
> programmer the proverbial middle finger at the same time! For some 
> reason it kind of makes me think of the register keyword...
> 
> Now, it would be funny if a compiler would output something like:
> 
> this function cannot be inlined, go ahead and try turning on link time 
> optimization, and try again? ;^)
> 
> 

Then, the programmer turns on link time optimization, and tries again. 
The compiler says, well, shit happens! No inline for you! Better try asm.

[toc] | [prev] | [next] | [standalone]


#82795

FromDavid Brown <david.brown@hesbynett.no>
Date2022-01-17 11:35 +0100
Message-ID<ss3gph$l5p$1@dont-email.me>
In reply to#82791
On 17/01/2022 08:51, Chris M. Thomasson wrote:
> On 1/16/2022 11:12 PM, David Brown wrote:
>> On 17/01/2022 06:38, Juha Nieminen wrote:
>>> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>>>> 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.
>>>
>>> And as a side note, the C standard also added support for 'inline'
>>> functions, except that it's a different and very weird version of it
>>> that
>>> to this day I still don't fully understand. It's like an 'inline' that's
>>> *not* an "ODR defeater". (It's so confusing that the vast, vast majority
>>> of C programmers just write "static inline" to get around the confusing
>>> part.)
>>>
>>
>> Yes, "inline" functions in C are a bit odd, and the semantics are not
>> the same as in C++.  As you say, the most common usage (and the only way
>> I use it) is to write "static inline" for functions to replace what
>> might pre-C99 have been a function-like macro.  The "inline" here is not
>> actually very significant - any decent C compiler will make its own
>> decisions about actual inlining optimisations, so a plain "static"
>> function would have the same effect.  To me, at least, the "static
>> inline" is a documentation of how you see the function and expect it to
>> be used.
> [...]
> 
> Imvvvho, using inline is almost akin to almost begging the compiler to
> actually inline the function. It certainly can say f-you, and give the
> programmer the proverbial middle finger at the same time! For some
> reason it kind of makes me think of the register keyword...
> 
> Now, it would be funny if a compiler would output something like:
> 
> this function cannot be inlined, go ahead and try turning on link time
> optimization, and try again? ;^)
> 
> 

"inline" does not make such demands of the compiler - in C or C++.  In
C++ it is very useful for letting you put definitions in headers (an
"ODR defeater", as some call it).  In C, with decent compilers, it is
much less useful as you could use a non-inline "static" function in a
header and get pretty much the same effect as a "static inline"
function.  To me, it is as much a documentation of the programmer
intention as anything else.

If you want to insist that the compiler really does inline a function,
you need to use compiler-specific features - like gcc/clang
"always_inline" attribute.  If you want the compiler to complain when it
can't inline a function, gcc has "-Winline" (or "-Werror=inline" for an
error).

[toc] | [prev] | [next] | [standalone]


#82794

FromJuha Nieminen <nospam@thanks.invalid>
Date2022-01-17 09:50 +0000
Message-ID<ss3e61$908$1@gioia.aioe.org>
In reply to#82790
David Brown <david.brown@hesbynett.no> wrote:
> Yes, "inline" functions in C are a bit odd, and the semantics are not
> the same as in C++.  As you say, the most common usage (and the only way
> I use it) is to write "static inline" for functions to replace what
> might pre-C99 have been a function-like macro.  The "inline" here is not
> actually very significant - any decent C compiler will make its own
> decisions about actual inlining optimisations, so a plain "static"
> function would have the same effect.  To me, at least, the "static
> inline" is a documentation of how you see the function and expect it to
> be used.

The difference between a 'static' (or 'static inline') function and a
(non-static) 'inline' function is that in the former case the function
gets instantiated as many times as there are compilation units that
call it (or in every compilation unit that includes the header, regardless
of whether anything calls it or not, as some more primitive C compilers
do. Yes, they exist.) In the latter case the function is instantiated
in the executable binary only once, just like in C++ (but in C you have
to explicitly tell *where* it's instantiated, while in C++ it's
automatic.)

Since as far as I remember you cannot have 'static' variables inside
an 'inline' function (unlike in C++), the only possible situation that
I can think of where you have to make an 'inline' function non-static
is if the function needs to have a unique pointer (eg. if you for
some reason need to compare function pointers). Or if you need to
squeeze even the last bits out of the executable binary size and do
not want the function to be duplicated.

Sometimes you can get away with using (non-static) 'inline' without
specifying where the function should be instantiated (if the compiler
never generates an actual function call), but I think that's
non-standard behavior.

[toc] | [prev] | [next] | [standalone]


#82804

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2022-01-17 14:39 -0500
Message-ID<ss4glv$ndi$1@dont-email.me>
In reply to#82794
On 1/17/22 4:50 AM, Juha Nieminen wrote:
...
> Since as far as I remember you cannot have 'static' variables inside
> an 'inline' function (unlike in C++),

That only applies to inline functions with external linkage, and only
for modifiable objects. The same is true of objects with thread storage
duration. Such functions are also prohibited from containing a reference
to an identifier with internal linkage. (C standard 6.7.4p3)

A key difference between C and C++ that is relevant to this thread is
that, in C++, 'inline' is an ignorable hint that inline substitution
should be performed. In C, it's an ignorable hint that "that calls to
the function be as fast as possible.", with the method where by that
might be achieved being unspecified.

[toc] | [prev] | [next] | [standalone]


#82809

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-01-17 15:34 -0800
Message-ID<865yqirl61.fsf@linuxsc.com>
In reply to#82804
James Kuyper <jameskuyper@alumni.caltech.edu> writes:

> On 1/17/22 4:50 AM, Juha Nieminen wrote:
> ...
>
>> Since as far as I remember you cannot have 'static' variables inside
>> an 'inline' function (unlike in C++),
>
> That only applies to inline functions with external linkage, and only
> for modifiable objects.  The same is true of objects with thread storage
> duration.  Such functions are also prohibited from containing a reference
> to an identifier with internal linkage.  (C standard 6.7.4p3)
>
> A key difference between C and C++ that is relevant to this thread is
> that, in C++, 'inline' is an ignorable hint that inline substitution
> should be performed.  In C, it's an ignorable hint that "that calls to
> the function be as fast as possible.", with the method where by that
> might be achieved being unspecified.

Note the sentence in the semantics portion of 6.7.4 of the C
standard that says

    The extent to which such suggestions are effective is
    implementation-defined.

So I think "implementation-defined" is more accurate than
"unspecified".

[toc] | [prev] | [next] | [standalone]


#82811

From"james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu>
Date2022-01-17 15:50 -0800
Message-ID<ee51ea67-646c-4498-9252-708f2df3d55en@googlegroups.com>
In reply to#82809
On Monday, January 17, 2022 at 6:35:03 PM UTC-5, Tim Rentsch wrote:
> James Kuyper <james...@alumni.caltech.edu> writes: 
...
> > A key difference between C and C++ that is relevant to this thread is 
> > that, in C++, 'inline' is an ignorable hint that inline substitution 
> > should be performed. In C, it's an ignorable hint that "that calls to 
> > the function be as fast as possible.", with the method where by that 
> > might be achieved being unspecified.
> Note the sentence in the semantics portion of 6.7.4 of the C 
> standard that says
> The extent to which such suggestions are effective is 
> implementation-defined.
> So I think "implementation-defined" is more accurate than 
> "unspecified".

"implementation-defined" behavior is unspecified behavior that an
implementation  is required to document, so both terms are correct, 
but "implementation-defined" is more specific. However, the point I
was making was about what the standard failed to specify, so
"unspecified" was relevant - that an implementation is required
to document the behavior wasn't.

[toc] | [prev] | [next] | [standalone]


#83714

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-04-25 03:42 -0700
Message-ID<86k0bd8mvr.fsf@linuxsc.com>
In reply to#82811
"james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> writes:

> On Monday, January 17, 2022 at 6:35:03 PM UTC-5, Tim Rentsch wrote:
>
>> James Kuyper <james...@alumni.caltech.edu> writes:
>
> ...
>
>>> A key difference between C and C++ that is relevant to this thread is
>>> that, in C++, 'inline' is an ignorable hint that inline substitution
>>> should be performed.  In C, it's an ignorable hint that "that calls to
>>> the function be as fast as possible.", with the method where by that
>>> might be achieved being unspecified.
>>
>> Note the sentence in the semantics portion of 6.7.4 of the C
>> standard that says The extent to which such suggestions are
>> effective is implementation-defined.  So I think
>> "implementation-defined" is more accurate than "unspecified".
>
> "implementation-defined" behavior is unspecified behavior that an
> implementation  is required to document, so both terms are correct,
> but "implementation-defined" is more specific.  However, the point I
> was making was about what the standard failed to specify, so
> "unspecified" was relevant - that an implementation is required
> to document the behavior wasn't.

On the contrary, it is quite relevant.  The requirement of being
documented means a developer can read the documentation and rely on
a particular behavior, and that is a huge difference.

[toc] | [prev] | [next] | [standalone]


#83732

From"james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu>
Date2022-04-25 08:48 -0700
Message-ID<325ab92c-4a5f-43ee-b5e5-3a7722f39d09n@googlegroups.com>
In reply to#83714
On Monday, April 25, 2022 at 6:43:03 AM UTC-4, Tim Rentsch wrote:
> "james...@alumni.caltech.edu" <james...@alumni.caltech.edu> writes: 
> 
> > On Monday, January 17, 2022 at 6:35:03 PM UTC-5, Tim Rentsch wrote: 
> > 
> >> James Kuyper <james...@alumni.caltech.edu> writes: 
> > 
> > ... 
> > 
> >>> A key difference between C and C++ that is relevant to this thread is 
> >>> that, in C++, 'inline' is an ignorable hint that inline substitution 
> >>> should be performed. In C, it's an ignorable hint that "that calls to 
> >>> the function be as fast as possible.", with the method where by that 
> >>> might be achieved being unspecified. 
> >> 
> >> Note the sentence in the semantics portion of 6.7.4 of the C 
> >> standard that says The extent to which such suggestions are 
> >> effective is implementation-defined. So I think 
> >> "implementation-defined" is more accurate than "unspecified". 
> > 
> > "implementation-defined" behavior is unspecified behavior that an 
> > implementation is required to document, so both terms are correct, 
> > but "implementation-defined" is more specific. However, the point I 
> > was making was about what the standard failed to specify, so 
> > "unspecified" was relevant - that an implementation is required 
> > to document the behavior wasn't.
> On the contrary, it is quite relevant. The requirement of being 
> documented means a developer can read the documentation and rely on 
> a particular behavior, and that is a huge difference.

Agreed. It is a huge difference. It is also a difference that is irrelevant to
the point I was making. I was not talking about whether or not a developer
could find out what the behavior was. I was only talking about whether or
not the standard specified a particular behavior, rather than a set
containing two or more permitted behaviors.

[toc] | [prev] | [next] | [standalone]


#82792

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2022-01-16 23:53 -0800
Message-ID<ss379q$j2d$1@dont-email.me>
In reply to#82789
On 1/16/2022 9:38 PM, Juha Nieminen wrote:
> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>> 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.
> 
> And as a side note, the C standard also added support for 'inline'
> functions, except that it's a different and very weird version of it that
> to this day I still don't fully understand. It's like an 'inline' that's
> *not* an "ODR defeater". (It's so confusing that the vast, vast majority
> of C programmers just write "static inline" to get around the confusing
> part.)

Yes, you are right. `inline` is clearly an "ODR defeater" in C++, but in 
C... not so much.

Firstly, `static inline` is a separate story. Most of the time `static` 
is all that's needed. In a quality compiler `static inline` is always 
redundant. It is 100% equivalent to plain `static`. There's never any 
tangible reason to use `static` and `inline` together. (Unless one wants 
to add `inline` for purely aesthetic reasons - to express how they feel 
about that function.)

The only thing that compiler needs to be able to inline a function call 
is access to the function's definition, to the full function's body. 
Once it can see the body, it can analyze and inline the calls (if it 
decides to inline). `static` functions are always defined inside their 
TUs, which means that they are already as inlinable as they can ever be. 
Declaring them `inline` on top of `static` achieves absolutely nothing.

So, the only tangible use of `inline` is with external linkage 
functions. External linkage implies that if an inline function ends up 
with a regular body, it should be one unique body in the whole program. 
And, thanks to that, the function will have unique address identity: 
same address in all TUs.

This is the objective. And this is where C and C++ take drastically 
different paths to that objective.

C++ achieves the above automatically through "generate them all; let 
linker sort them out" approach: compiler nonchalantly emits bodies for 
external linkage inline functions in different TUs, then linker discards 
all same-named bodies except one (see "weak symbols").

C, on the other hand, continues to stick to pedantically manual approach 
to ODR: it is the user's responsibility to ensure existence and 
uniqueness of a regular body generated for an inline function (just in 
case that body becomes necessary). The user chooses the TU for that body 
and the user triggers it by using the `extern inline` combination.

So, yes, in C `inline` is not really an "ODR defeater". `inline` 
definitions in C do not emit function bodies, which means that there's 
nothing to defeat. `extern inline` declaration does emit a function 
body, but the burden of making it (and making it only once) is placed 
upon the user.

-- 
Best regards,
Andrey Tarasevich

[toc] | [prev] | [next] | [standalone]


#82808

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2022-01-17 15:29 -0800
Message-ID<86a6furle2.fsf@linuxsc.com>
In reply to#82792
Andrey Tarasevich <andreytarasevich@hotmail.com> writes:

> On 1/16/2022 9:38 PM, Juha Nieminen wrote:
>
>> Andrey Tarasevich <andreytarasevich@hotmail.com> wrote:
>>
>>> 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.
>>
>> And as a side note, the C standard also added support for
>> 'inline' functions, except that it's a different and very weird
>> version of it that to this day I still don't fully understand.
>> It's like an 'inline' that's *not* an "ODR defeater".  (It's so
>> confusing that the vast, vast majority of C programmers just
>> write "static inline" to get around the confusing part.)
>
> Yes, you are right.  `inline` is clearly an "ODR defeater" in C++,
> but in C... not so much.
>
> Firstly, `static inline` is a separate story.  Most of the time
> static` is all that's needed.  In a quality compiler `static
> inline` is always redundant.  It is 100% equivalent to plain
> `static`.  There's never any tangible reason to use `static` and
> `inline` together.  [...]

In C++ I expect that's right.  In C though there is a key
difference that may provide a reason to use 'inline'.  In C
declaring or defining a function 'inline' can provide additional
guarantees beyond just using 'static'.  In the semantics section
of 6.7.4 of the C standard, there is this excerpt:

    Making a function an inline function suggests that calls to
    the function be as fast as possible.  The extent to which
    such suggestions are effective is implementation-defined.

Note the second sentence.  C implementations must document
what happens with 'inline', but there is no such requirement
for 'static'.

(I should add that I'm assuming that C++ does not impose a
similar requirement.  I have not tried looking in the C++
standard to see if that is the case.)

[toc] | [prev] | [next] | [standalone]


#82796

FromBonita Montero <Bonita.Montero@gmail.com>
Date2022-01-17 12:40 +0100
Message-ID<ss3kjc$sbb$1@dont-email.me>
In reply to#82769
Am 14.01.2022 um 02:51 schrieb Andrey Tarasevich:

> 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. ...

That's true for inline-variables but for inline-functions only parti-
tially. For inline functions inline is also a hint for the compiler
to inline the code in the calling code. But this is only a hint and
not mandantory.

[toc] | [prev] | [next] | [standalone]


#82800

FromAndrey Tarasevich <andreytarasevich@hotmail.com>
Date2022-01-17 10:13 -0800
Message-ID<ss4bkq$e34$1@dont-email.me>
In reply to#82796
On 1/17/2022 3:40 AM, Bonita Montero wrote:
> Am 14.01.2022 um 02:51 schrieb Andrey Tarasevich:
> 
>> 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. ...
> 
> That's true for inline-variables but for inline-functions only parti-
> tially. For inline functions inline is also a hint for the compiler
> to inline the code in the calling code. But this is only a hint and
> not mandantory.

Um... Once again "only a hint to inline and not mandantory" is 
completely meaningless wording within the context of a formal document. 
Such wording should be relegated to a footnote, to explain the etymology 
of the keyword.

Currently, this is essentially a defect in the standard, which only 
serves to confuse people.

The proper wording describing the purpose and intent of `inline` should 
say something along the lines of "the purpose of `inline` keyword is to 
make the definition of a function with external linkage visible in all 
translation units without triggering an ODR violation".

Once they've stated that, they can also add a bit of rationale, e.g. 
"this helps facilitate inlining and many other useful optimizations"

Note, BTW, that when a full function body is visible to the compiler, 
the optimization benefits of such visibility go far beyond inlining.

-- 
Best regards,
Andrey Tarasevich

[toc] | [prev] | [next] | [standalone]


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

Back to top | Article view | comp.lang.c++


csiph-web