Use Inline in class?

I

Immortal Nephi

I want to know if the practice is the best. Do I need to place inline
keyword inside class definition or outside member function
definition. For example

class A
{
public:
A();
~A();

inline void Test(); // should place inline here?
};

inline void A::Test() // should place inline here?
{
{
 
H

HL

I want to know if the practice is the best. Do I need to place inline
keyword inside class definition or outside member function
definition. For example

class A
{
public:
A();
~A();

inline void Test(); // should place inline here? no need
};

inline void A::Test() // should place inline here?
{
{
yes, you need.

another way is to define func in class.
class A{
public:
void Test(){...};
};
Test is refered as inline.
 
J

Juha Nieminen

Andrey said:
If you want to define your inline member function outside the class
definition (as in your example above), you only need to specify 'inline'
in the member definition (the second 'inline' in your example)

If this is the case, why is the keyword 'inline' even supported inside
class definitions? Isn't it completely obsolete and a no-op there?
(Basically there's not even one single case where specifying that
keyword in the class definition makes a difference.)
 
J

James Kanze

If this is the case, why is the keyword 'inline' even
supported inside class definitions? Isn't it completely
obsolete and a no-op there? (Basically there's not even one
single case where specifying that keyword in the class
definition makes a difference.)

You can specify inline on either the definition or any
declaration which precedes it, and the function will be inline.
Current practice is to specify it on the definition, but at
least one earlier compiler I used required it to be specified on
the first declaration that appeared.

Of course, current best pratice is not to use inline at all, so
the problem doesn't occur.
 
J

joseph cook

Of course, current best practice is not to use inline at all, so
the problem doesn't occur.

Why do you say this? In-lining functions in a header file can be
critical for performance reasons.
Thanks,
Joe Cook
 
J

James Kanze

Why do you say this?

Because it increases coupling.
In-lining functions in a header file can be critical for
performance reasons.

Really? I never use it, and I've not had any performance
problems.

If you do actually have a performance problem, and the profiler
shows that it is in a tight loop where you do call a non-inlined
function, then inlining it is a simple and cheap optimization.
Using inline before the profiler says you have to, however, is
premature optimization.
 
G

Gennaro Prota

Alf said:
* James Kanze:
> [...]
If you do actually have a performance problem, and the profiler
shows that it is in a tight loop where you do call a non-inlined
function, then inlining it is a simple and cheap optimization.
Using inline before the profiler says you have to, however, is
premature optimization.

Inlining things in headers is a technique that saves programmer's time
both for initial development, for use of the header, and for
maintainance (which reportedly constitutes about 80% of all programming
work).

I think that if this is really your issue (hardly, but I'll assume you
have some measurements) then you (or your users in the case e.g. of
libraries, for which I've often heard the "header-only is easier"
claim) are likely to work with a severely limited environment and
toolset. To me, creating one more file is just a matter of issuing ":e
filename" and the file contents get initialized automatically with all
that can be written automatically. Similarly for building. As to
maintenance I really don't understand: what time do you save?
 
J

James Kanze

* James Kanze:
Inlining things in headers is a technique that saves
programmer's time both for initial development, for use of the
header, and for maintainance (which reportedly constitutes
about 80% of all programming work).

I don't know where you get that from. It is a nightmare with
regards to maintenance, easily doubling the effort required.
(To begin with, if you don't know if the function is inlined or
not, you don't even know in which file to look for it. And of
course, if you have to modify it, then all of the client code
needs to be recompiled.)
I agree that doing inlining for reasons of performance would
be premature optimization, of the kind that might even
influence runtime in a negative way, and bring in unwanted
coupling and have other undesirable effect.
However, used as a means for programmer productivity, not as
premature optimization, its effect on coupling is generally
negligible.

If it's used in a template, it's negligible, because the
template code has to be included anyway (at least with most
current compilers). If it's not a template, however, the effect
in practice can be quite high.

Obviously, it's only one factor: you can write impossible to
maintain code without a single inline function, and carefully
used, you can minimize the impact. But globally, all of the
coding guidelines I've seen for application code forbid inline
functions---and usually also require user defined
implementations of the functions the compiler will generate by
default as well, since the compiler generated versions are
inline. (The rules for library code are somewhat different,
since you often have to guess where the client code's
bottlenecks might occur.)
It can even reduce the number of files that must be opened and
read during a build. I think the programmer who's afraid of
using std::vector just because it's perceived as a large
header & requires full def of element type, is seriously
misguided.

That, certainly. But std::vector is (hopefully) stable code,
which isn't evolving while you're working. So you won't end up
having to recompile everything because there was a small
correction in the implementation somewhere. (If you upgrade
your compiler, of course, you'll get a new version of
std::vector. But if you upgrade your compiler, you have to
recompile everything anyway, since all of the object files
depend in some way on the compiler. On the other hand, you
shouldn't be upgrading the compiler very often---maybe once
every two or three years, at the most.)
 
I

Ian Collins

James said:
But globally, all of the
coding guidelines I've seen for application code forbid inline
functions---and usually also require user defined
implementations of the functions the compiler will generate by
default as well, since the compiler generated versions are
inline.

Where's the problem with inline compiler generated functions?
 
J

James Kanze

* Gennaro Prota:
Alf said:
* James Kanze:
[...]
If you do actually have a performance problem, and the
profiler shows that it is in a tight loop where you do
call a non-inlined function, then inlining it is a simple
and cheap optimization. Using inline before the profiler
says you have to, however, is premature optimization.
Inlining things in headers is a technique that saves
programmer's time both for initial development, for use of
the header, and for maintainance (which reportedly
constitutes about 80% of all programming work).
I think that if this is really your issue (hardly, but I'll
assume you have some measurements) then you (or your users
in the case e.g. of libraries, for which I've often heard
the "header-only is easier" claim) are likely to work with a
severely limited environment and toolset. To me, creating
one more file is just a matter of issuing ":e filename" and
the file contents get initialized automatically with all
that can be written automatically. Similarly for building.
It's also easy to write Perl. ;-)

But we both agree that maintenance is an important issue:).
For things that are defined in the header file you only need
to look at one file, affecting continuity, and you see the
relevant definition in context.

There are some arguments in favor of "all in the header", in
certain conditions. (If you're distributing a library over
multiple platforms, for example, it certainly makes the
distribution easy.) For the most part, however, code isn't (and
shouldn't be) designed as a monolithic block. Before attacking
the maintenance, you read the documentation, to understand the
basic role of the class in the context of the application. From
the documentation and the test results, you should be able to
determine directly which function is misbehaving (otherwise,
your tests aren't adequately precise), and usually, even, have a
fair idea as to why it is misbehaving. So you don't need
authorization to check out the header; you can just check out
the implementation file for the function, make the correction,
and be done with it. Even in less perfect situations (and I'll
admit, not every organization runs as smoothly as I just
described), you'll generally have to look at several different
classes, in several different headers, before deciding which
implementation file needs working on. And in those classes
which you don't want to modify (usually the majority), you don't
want to have to search through tons of implementation code to
find the relevant declarations; Java without (well written)
Javadoc is unmaintainable, but you can actually produce readable
class definitions in C++. (Even with inline functions---the
inline functions will normally be defined outside of the class
anyway.)
 
J

James Kanze

Where's the problem with inline compiler generated functions?

The day you have to change them (and they cease to become
compiler generated), you have to modify the header.

In the end, implementation details don't belong in the header.
We're stuck with regards to private data and functions (although
the compilation firewall can limit the problems), but for the
rest, you only put what is necessary for the client in the
header. The implementation of a function, or even the fact that
the implementation is compiler generated, is an implementation
detail.
 
J

James Kanze

* James Kanze:

[...]
This sounds very much like arbitrary decisions that have made
themselves into law, and are not being rationalizated is if
they were meaningful.

Actually, it's all based on concrete experience.

If you prefer to ignore concrete experience, that's your
privilege.
 
I

Ian Collins

James said:
The day you have to change them (and they cease to become
compiler generated), you have to modify the header.
I'd expect the reason a class would require an explicit version of a
compiler generated function would be a change to its data members.

I guess it all comes back to the old discussion about build times. I'm
used to an environment where changing headers is a normal part of the
development process.
In the end, implementation details don't belong in the header.

I can't argue with that.
We're stuck with regards to private data and functions (although
the compilation firewall can limit the problems), but for the
rest, you only put what is necessary for the client in the
header. The implementation of a function, or even the fact that
the implementation is compiler generated, is an implementation
detail.
Yes and no - it is a detail, but it's a hidden detail.
 
G

Gennaro Prota

James said:
In the end, implementation details don't belong in the header.
We're stuck with regards to private data and functions (although
the compilation firewall can limit the problems), but for the
rest, you only put what is necessary for the client in the
header. The implementation of a function, or even the fact that
the implementation is compiler generated, is an implementation
detail.

Note that in C++0x we should finally be able to require
compiler-generation of special member functions without making them
inline:

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2346.htm>
 
G

Greg Herlihy

Java without (well written)
Javadoc is unmaintainable, but you can actually produce readable
class definitions in C++.  (Even with inline functions---the
inline functions will normally be defined outside of the class
anyway.)

About the only programmers who could conceivably think that that Java
classes are somehow "unmaintaintable" - might be those who are still
using 60's-era program editors to write their code. Because, in
practice (that is, with modern tools), there is no question that Java
learned from C++ mistakes in the area of program interfaces - and
(among other improvements) eliminated the pointless redundancy and
needless exposure of class implementation details found in C++.

For one, a Java programmer can simply "collapse" a class' function
bodies - in order to examine the class's pure interface. Moreover,
when distributing the header of a Java "package" (comparable to a C++
library), the package's (automatically-generated) interface file
includes only those class members and methods that are accessible to
clients. Otherwise, all non-accessible class methods (and members) are
simply not present in the package interface file at all. C++, of
course requires that a class interface include protected and private
methods and members. Note that - even though these methods and members
are not "accessible" - they nonetheless are "visible", and can
therefore cause senseless naming conflicts and access violations for
clients of the interface.

Greg
 
J

James Kanze

I'd expect the reason a class would require an explicit
version of a compiler generated function would be a change to
its data members.

You've never added logging or event notifications?

Typically, of course, you're right, and the compiler generated
inlines are generally less of a problem than user defined ones.
In fact, the main reason given for avoiding them was code bloat;
in the case of constructors and destructors, the apparently
"empty" function can generate a lot of code.

In my own code (i.e. code where I don't have to follow
externally imposed guidelines), I vary somewhat, using common
sense and my knowledge of the class' semantics: I'd certainly
not bother defining the compiler generated defaults for
something like complex, for example, where as if the class has
some real, application level behavior, I probably would.

And of course, if the code is a template, the rules are
definitelyl relaxed, because the source level coupling is
already there anyway.
 
J

Juha Nieminen

Greg said:
For one, a Java programmer can simply "collapse" a class' function
bodies - in order to examine the class's pure interface.

It sounds to me that you are saying that you require rather advanced,
very Java-conscious editors in order to make Java source code readable.
That a regular text editor won't do. That sounds to me like the exact
opposite of what you are attempting to say: Java source code is by
default so complicated that fancy editing programs are needed to make it
readable.
C++, of
course requires that a class interface include protected and private
methods and members. Note that - even though these methods and members
are not "accessible" - they nonetheless are "visible", and can
therefore cause senseless naming conflicts and access violations for
clients of the interface.

Naming conflicts and access violations? What kind of bullshit is this?
 
J

Juha Nieminen

James said:
Really? I never use it, and I've not had any performance
problems.

I think you are underestimating the importance of inlining with
respect to speed (and even executable size).

For example, a small program I made to test the speed of a (very
template-heavy) memory allocator library I made, runs in 16 seconds, and
the executable is 10kB (stripped).

If I add the compiling option -fno-inline, which stops gcc from
inlining any function, all the other optimizations being the same, the
program now runs in 1 minute 11 seconds, and the executable is 18kB in size.

Not only does inlining make the program a lot faster, it even makes it
considerably smaller (debunking the common misconception most people
have about inlining making executables bigger).
 
L

Lionel B

without (well written)
[...]

C++, of course
requires that a class interface include protected and private methods
and members. Note that - even though these methods and members are not
"accessible" - they nonetheless are "visible", and can therefore cause
senseless naming conflicts and access violations for clients of the
interface.

Huh? Example?
 
I

Ian Collins

James said:
You've never added logging or event notifications?

Typically, of course, you're right, and the compiler generated
inlines are generally less of a problem than user defined ones.
In fact, the main reason given for avoiding them was code bloat;
in the case of constructors and destructors, the apparently
"empty" function can generate a lot of code.
Doesn't the standard require at most one copy in the entire program of a
non-static inline function? I'm assuming compiler generated functions
fall into this category. Or do they?
 

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,019
Latest member
RoxannaSta

Latest Threads

Top