Topic: template function inlining
Author: "Pavel Kuznetsov" <decraft@no--spam--bigfoot.com>
Date: Mon, 30 Apr 2001 08:56:57 GMT Raw View
Thanks to everyone who submitted answers.
It seems I've got it.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Pavel Kuznetsov" <decraft@no--spam--bigfoot.com>
Date: Fri, 27 Apr 2001 23:06:06 GMT Raw View
Well, it seems that I had posted not quite clear question.
Let's put it this way:
1) In "One definition rule" (3.2.3) we see:
"Every program shall contain exactly one definition of
every non-inline function or object that is used in that
program... An inline function shall be defined in every
translation unit in which it is used."
2) Later in 3.2.5:
"There can be more than one definition of ...
...non-static function template (14.5.5)...
...in a program provided that each definition
appears in a different translation unit..."
So my question is: is it stated in Standard how compiler
should treat template functions not marked as inline?
Should it create one specialization per program and call
that function from everywhere or create one specialization
per translation unit, or put function inline (probably not)?
I.e. what difference between following two examples:
[Example 1:
// header file
template<typename T> void foo(T t)
{
// ...
}
// first .cpp file
void bar()
{
int i = 0;
foo(i); // note: foo<int>() called
}
// second .cpp file
void gee()
{
int n = 0;
foo(n); // note: same foo<int>() called
}
--end example 1]
[Example 2:
// header file
// note __inline__
template<typename T> inline void foo(T t)
{
// ...
}
// first .cpp file
void bar()
{
int i = 0;
foo(i);
}
// second .cpp file
void gee()
{
int n = 0;
foo(n);
}
--end example 2]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Andrea Ferro" <AndreaF@UrkaDVD.it>
Date: Sun, 29 Apr 2001 13:19:15 GMT Raw View
"Pavel Kuznetsov" <decraft@no--spam--bigfoot.com> wrote in message
news:9cbc8h$8a4$1@taliesin.netcom.net.uk...
> Well, it seems that I had posted not quite clear question.
> Let's put it this way:
>
> 1) In "One definition rule" (3.2.3) we see:
> "Every program shall contain exactly one definition of
> every non-inline function or object that is used in that
> program... An inline function shall be defined in every
> translation unit in which it is used."
>
> 2) Later in 3.2.5:
> "There can be more than one definition of ...
> ...non-static function template (14.5.5)...
> ...in a program provided that each definition
> appears in a different translation unit..."
>
> So my question is: is it stated in Standard how compiler
> should treat template functions not marked as inline?
Yes. But do not ask a pointer, it is all scattered.
> Should it create one specialization per program and call
> that function from everywhere or create one specialization
> per translation unit, or put function inline (probably not)?
First of all a compiler is never forced to inline nor forced to not inline. A
compiler can inline anything it sees fit and can refuse to inline anything that
is declared inline. If a function is declared inline the compiler can either
inline it or provide a static non inlined version of it and not expose that to
other translation units (no external linkage) or even provide a non inlined
version of it AND provide it externally. It should NON rely on the presence of
an external linkage version of it from another translation unit. If the function
is not declared inline (nor static) then it must provide a version of it with
external linkage, but it can also expand it inline in any use of it in the
current translation unit ignoring the externally visible version.
The same is for a template (with a little difference if export is used, but this
is not the case).
However note that if the compiler does provide a version of a function declared
inline or of a template function specialization that has external linkage, it
must mark it as a special case of external linkage. It is one of those
externally visible blocks of code that the linker must not use for "cross
reference" resolution beween different object code: it just must put one and
only one version of that code in the exe. It is a sort of "common block" in
fortran terms, beside it contains code.
> I.e. what difference between following two examples:
None. Beside the fact that some compilers would expand one case inline and the
other not. But that's an implementation choice. VC7 for one will decide it
according to both switch settings (expand none/expand any suitable/exapand only
those declare inline if possible). To decide that a function marked inline can
be expanded it checks for recursion (of course) and maybe for size of expanded
code (not inline if very large). If instructed to expand "any suitable" it
checks for size and recursion (this case I'm sure).
Just to have a feel of the (relative) importance of the inline keyword, given
this code:
// file foo.hpp
int foo();
// file foo.cpp
#include "foo.hpp"
int foo()
{
return 1;
}
// file bar.cpp
#include "foo.hpp"
int bar()
{
return 2;
}
int foobar()
{
return foo()+bar();
}
contains no inline keyword. VC7 (100% compliant from this point of view) if
instructed to inline any suitable will translate foobar as:
int foobar()
{
return foo()+2;
}
and if instructed to inline any suitable and also to optimize globally will
translate foobar as:
int foobar()
{
return 3;
}
even if foo definition is in another translation unit (not to mention it is not
declared inline!).
In other words, inline does make a difference in the treatment of external
linkage but relates to actual inlining just as much as register relates to
register allocation.
--
Andrea Ferro
---------
Brainbench C++ Master. Scored higher than 97% of previous takers
Scores: Overall 4.46, Conceptual 5.0, Problem-Solving 5.0
More info http://www.brainbench.com/transcript.jsp?pid=2522556
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Pavel Kuznetsov" <--no--spam--decraft@bigfoot.com>
Date: Mon, 16 Apr 2001 17:20:35 GMT Raw View
Could somebody please clarify for me what happens
according to Standard when template function is not
declared as inline. Can I consider that it is inline
implicitly.
[Example:
template<typename T> void f(T t)
{
// ...
}
--end example]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Valentin.Bonnard@free.fr (Valentin Bonnard)
Date: Mon, 16 Apr 2001 18:15:13 GMT Raw View
"Pavel Kuznetsov" wrote:
> Could somebody please clarify for me what happens
> according to Standard when template function is not
> declared as inline. Can I consider that it is inline
> implicitly.
No, it is not inline, but you can define it in every
translation unit that uses it, just as an inline
function.
Or you can define the template just once, and use
explicit instantiation:
// foo.hh
template <typename T> void foo (T);
// main.cc
#include "foo.hh"
int main () {
foo (3);
}
// foo.cc
template <typename T> void foo (T x) {
x + x;
}
// foo is used on int
template void foo (int);
Or you can use ``export'' to define templates only once,
just like non-template non-inline functions, if your compiler
handles it.
--
Valentin Bonnard
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Francis Glassborow <francis.glassborow@ntlworld.com>
Date: Tue, 17 Apr 2001 00:25:53 GMT Raw View
In article <9bbkdj$ism$1@taliesin.netcom.net.uk>, Pavel Kuznetsov <--no-
-spam--decraft@bigfoot.com> writes
>Could somebody please clarify for me what happens
>according to Standard when template function is not
>declared as inline. Can I consider that it is inline
>implicitly.
I would hope not, that would be a disaster.
>
>[Example:
>
> template<typename T> void f(T t)
> {
> // ...
> }
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: jpotter@falcon.lhup.edu (John Potter)
Date: Tue, 17 Apr 2001 03:43:54 GMT Raw View
On Mon, 16 Apr 2001 17:20:35 GMT, "Pavel Kuznetsov"
<--no--spam--decraft@bigfoot.com> wrote:
> Could somebody please clarify for me what happens
> according to Standard when template function is not
> declared as inline. Can I consider that it is inline
> implicitly.
>
> [Example:
>
> template<typename T> void f(T t)
> {
> // ...
> }
>
> --end example]
Sure. That would be just as valid as assuming that a template function
which is explicitely declared inline would be inlined. An
implementation may inline any function without direction and may not
inline any function with an inline directive. You may ass-u-me anything
you like.
John
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]