What gets inlined?

S

Steven T. Hatton

I know this is, to some extent, implementation dependent, but since the
Standard specifies an inline specifier, there must be some "reasonable
assumptions" I can make about what should happen when I inline a function.

Suppose I have something like this (which, BTW is currently broken in
Qt-4-rc1):

inline QWidget* vBox(QWidget* parent) {
QWidget* box = new QWidget(parent);
QVBoxLayout* boxLayout = new QVBoxLayout(box);
box->setLayout(boxLayout);
return box;
}

Clearly, there will be a lot happening between the entry point, and the
return from the function. My understanding is that all of the object code
involved will not be inlined, and only the compiled representation of the
function calls will be placed inline. Is this correct?
 
A

Alf P. Steinbach

* Steven T. Hatton:
I know this is, to some extent, implementation dependent, but since the
Standard specifies an inline specifier, there must be some "reasonable
assumptions" I can make about what should happen when I inline a function.

Suppose I have something like this (which, BTW is currently broken in
Qt-4-rc1):

inline QWidget* vBox(QWidget* parent) {
QWidget* box = new QWidget(parent);
QVBoxLayout* boxLayout = new QVBoxLayout(box);
box->setLayout(boxLayout);
return box;
}

Clearly, there will be a lot happening between the entry point, and the
return from the function. My understanding is that all of the object code
involved will not be inlined, and only the compiled representation of the
function calls will be placed inline. Is this correct?

No. Essentially you can't assume anything. And that's a FAQ:

<url: http://www.parashift.com/c++-faq-lite/inline-functions.html#faq-9.3>

If you want optimization, tell your compiler to optimize.

If you want control over inlining, which is something else, use
compiler-specific language extensions.
 
S

Steven T. Hatton

Rolf said:
Yes. You can expect to be able to define it in multiple translation units
without getting an error. However, you can't assume any inlining to happen
or not happen.

My question has to do with _what_ gets inlined _if_ the compiler inlines the
function? I suspect that doesn't vary a lot between implementations, but I
could be wrong.
 
V

velthuijsen

Everywhere that the inlined function is visible the function call gets
replaced by the code in the function with appropiate substitutions for
return value and the passed variable(s).
 
V

velthuijsen

Keep forgetting that Google quick reply chucks out the reply to text so
here again:
My question has to do with _what_ gets inlined _if_ the compiler inlines the
function? I suspect that doesn't vary a lot between implementations, but I
could be wrong.
--
If our hypothesis is about anything and not about some one or more
particular things, then our deductions constitute mathematics. Thus
mathematics may be defined as the subject in which we never know what we
are talking about, nor whether what we are saying is true.-Bertrand Russell

If inline occurs the following:
Everywhere that the inlined function is visible the function call gets
replaced by the code in the function with appropiate substitutions for
return value and the passed variable(s).
 
R

Rolf Magnus

Steven said:
I know this is, to some extent, implementation dependent, but since the
Standard specifies an inline specifier, there must be some "reasonable
assumptions" I can make about what should happen when I inline a function.

Yes. You can expect to be able to define it in multiple translation units
without getting an error. However, you can't assume any inlining to happen
or not happen.
 
S

Steven T. Hatton

Everywhere that the inlined function is visible the function call gets
replaced by the code in the function with appropiate substitutions for
return value and the passed variable(s).

What happens when the inlined function has calls to other functions? I
believe it is correct to assume that the object code for these functions
is /not/ inlined. Unless of course those functions are also declared
inline, and the compile feels like doing it.
 
M

msalters

(e-mail address removed) schreef:
Everywhere that the inlined function is visible
( and possibly other places as well )
the function call gets replaced
( it the compiler follows your hint)
by the code in the function
( or parts of it, e.g. if the compiler can't inline everything)
with appropiate substitutions for return value and the passed
variable(s).

It's very much a hint to the compiler. What it does with such a hint
is intentionally obscure. E.g. I'd expect a very good compiler not to
inline a catch(...) clause. That's typically cold code, keep that in
a separate function but do inline the try{ } body.

HTH,
Michiel Salters
 
C

Chris Theis

Steven T. Hatton said:
What happens when the inlined function has calls to other functions? I
believe it is correct to assume that the object code for these functions
is /not/ inlined. Unless of course those functions are also declared
inline, and the compile feels like doing it.

Whether the compiler will inline & substitute also subsequent function calls
in inlined functions is at the mercy of your compiler. There is no general
rule for this.

Cheers
Chris
 
J

John Carson

Steven T. Hatton said:
I know this is, to some extent, implementation dependent, but since
the Standard specifies an inline specifier, there must be some
"reasonable assumptions" I can make about what should happen when I
inline a function.

Suppose I have something like this (which, BTW is currently broken in
Qt-4-rc1):

inline QWidget* vBox(QWidget* parent) {
QWidget* box = new QWidget(parent);
QVBoxLayout* boxLayout = new QVBoxLayout(box);
box->setLayout(boxLayout);
return box;
}

Clearly, there will be a lot happening between the entry point, and
the return from the function. My understanding is that all of the
object code involved will not be inlined, and only the compiled
representation of the function calls will be placed inline. Is this
correct? --


Generally, yes, unless the functions called are themselves inline functions.

Lots of people in these threads talk about it being "all up to the compiler"
to inline or not inline as it sees fit. With VC++, there is a switch that
turns on "auto-inlining", whereby the compiler can inline any function it
wants. With the default settings, however, no function is inlined unless the
inline keyword is used (or the function definition is in the class
declaration, since this is equivalent to using the inline keyword), i.e.,
use of the inline keyword is a necessary, though not sufficient, condition
for a function to be inlined. For other compilers, I guess you have to
consult their documentation.
 
A

Alf P. Steinbach

* John Carson:
Lots of people in these threads talk about it being "all up to the compiler"
to inline or not inline as it sees fit. With VC++, there is a switch that
turns on "auto-inlining", whereby the compiler can inline any function it
wants. With the default settings, however, no function is inlined unless the
inline keyword is used (or the function definition is in the class
declaration, since this is equivalent to using the inline keyword), i.e.,
use of the inline keyword is a necessary, though not sufficient, condition
for a function to be inlined.

Sorry, the above is incorrect, at least for MSVC 7.1.

With MSVC 7.1 (to be precise, which is what I just checked out using a
little test program) there is a switch that turns _off_ the automatic
inlining behavior. I.e., with that switch the word 'inline' is required.
And AFAICS there's no switch to _on_ automatic inlining, it's the default.

In the for-dummies Visual Studio IDE the automatic inlining off switch is
set by default, and, just to give readers who don't have that IDE an
impression of how intelligent the designers were, switches that make the
compiler behave as standard C++ wrt. wchar_t type, 'main', RTTI and more are
not set by default in the IDE -- it's not a Good Idea to use the compiler
behavior in a default Microsoft IDE project as any indication of anything.

For other compilers, I guess you have to consult their documentation.

That would also be a good idea for MSVC. ;-)

/Ob0 Disables inline expansion, which is on by default.

Not taking the documentation's word for it, because it's often wrong, I
tested using a simple program and checking the generated machine code.

Advice: always test reality.


Hth.,

- Alf
 
J

John Carson

Alf P. Steinbach said:
* John Carson:

Sorry, the above is incorrect, at least for MSVC 7.1.

With MSVC 7.1 (to be precise, which is what I just checked out using a
little test program) there is a switch that turns _off_ the automatic
inlining behavior. I.e., with that switch the word 'inline' is
required. And AFAICS there's no switch to _on_ automatic inlining,
it's the default.

It is controlled by the /Ob switch. /Ob0 turn off inlining, as you state,
/Ob1 gives manual inlining and /Ob2 gives auto inlining. If you create a
project in the IDE in VC++ 7.1, then /Ob2 (automatic) is the default in
Release mode. I stand corrected on this. It is a change from VC++ 6.0, where
/Ob1 is the IDE default. The change in defaults was made in VC++ 7.0.
 
V

velthuijsen

msalters said:
(e-mail address removed) schreef:
( and possibly other places as well )

Could you please explain what you mean by this? And how does the
compiler/linker figure out what code to use if it can't see the code?
( it the compiler follows your hint)

Just responded to the lets assume the compiler does follow your hint :)
( or parts of it, e.g. if the compiler can't inline everything)

What compiler(s) implement this at the moment? For the few I know it's
an all or nothing afair.
 
O

Old Wolf

Steven said:
Suppose I have something like this (which, BTW is currently broken
in Qt-4-rc1):

inline QWidget* vBox(QWidget* parent) {
QWidget* box = new QWidget(parent);
QVBoxLayout* boxLayout = new QVBoxLayout(box);
box->setLayout(boxLayout);
return box;
}

This code is highly non-exception-safe. Is that what you meant
by 'broken' ? If the 'new QVBoxLayout(box)' call fails (either
due to lack of memory, or the layout throwing an exception),
then resources will be leaked.
I can't see how a project that's supposed to be the basis of
a stable application, can justify such dreadful code ?
 
R

Rolf Magnus

Old said:
This code is highly non-exception-safe. Is that what you meant
by 'broken' ?

Probably not, considering that Qt doesn't use exceptions.
If the 'new QVBoxLayout(box)' call fails (either
due to lack of memory, or the layout throwing an exception),
then resources will be leaked.

Probably the exception will actually not be caught at all an the process be
terminated. There isn't much that the program could do anyway.
I can't see how a project that's supposed to be the basis of
a stable application, can justify such dreadful code ?

If there is no memory left, the system is likely to be next to unresponsive
due to excessive swapping. And then, the program cannot do much to react to
an out-of-memory condition. Opening a window to tell that to the user - or
even creating a string would require more memory and so cannot be done in
an exception handler for out-of-memory exceptions.
 
S

Steven T. Hatton

Old said:
This code is highly non-exception-safe. Is that what you meant
by 'broken' ? If the 'new QVBoxLayout(box)' call fails (either
due to lack of memory, or the layout throwing an exception),
then resources will be leaked.
I can't see how a project that's supposed to be the basis of
a stable application, can justify such dreadful code ?

Qt cleans up after itself. If QVBoxLayout(box) fails, parent still has a
handle on box, and will destroy box when it's destroyed. As it turns out,
Qt does not support the functionality I was trying to use. The
documentation is out of sync with the current state of the development code
base. I believe they are dumbing down the widget and layout creation
features because too many people found it confusing. Unfortunately, I took
the time, and made the effort to figure it out. Once I understood it, I
was able to do some really slick stuff with it. Now that they're taking it
out, all my code is deprecated. :(
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top