Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #82759 > unrolled thread
| Started by | Muttley@dastardlyhq.com |
|---|---|
| First post | 2022-01-12 16:34 +0000 |
| Last post | 2022-01-18 09:20 +0100 |
| Articles | 20 on this page of 47 — 13 participants |
Back to article view | Back to comp.lang.c++
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 →
| From | "Alf P. Steinbach" <alf.p.steinbach@gmail.com> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-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]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2022-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]
| From | "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> |
|---|---|
| Date | 2022-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]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2022-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]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2022-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]
| From | James Kuyper <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | "james...@alumni.caltech.edu" <jameskuyper@alumni.caltech.edu> |
|---|---|
| Date | 2022-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]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-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]
| From | Tim Rentsch <tr.17687@z991.linuxsc.com> |
|---|---|
| Date | 2022-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]
| From | Bonita Montero <Bonita.Montero@gmail.com> |
|---|---|
| Date | 2022-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]
| From | Andrey Tarasevich <andreytarasevich@hotmail.com> |
|---|---|
| Date | 2022-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