Topic: optimizer & inline function
Author: Michael Kilburn <crusader.mike@gmail.com>
Date: Fri, 27 Feb 2009 11:38:04 CST Raw View
Hi,
How far optimizer could go when expanding inline functions? In
particular in this code:
inline void func(SmartPtr<MyClass> p)
{
if (smth) throw X;
p->?; // use p
}
func(new MyClass(?));
is it guaranteed that function arguments are constructed before first
line of the inlined function is executed? I.e. is compiler allowed to
postpone p's construction (given that if('smth') does not reference
p)?
Logical answer would be "no", but I'd like to understand why -- I
could not find anything in standard that guarantees p's construction.
Michael.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: =?iso-8859-2?B?Smn47SBQYWxl6GVr?= <jpalecek@web.de>
Date: Sat, 28 Feb 2009 12:26:54 CST Raw View
On Fri, 27 Feb 2009 18:38:04 +0100, Michael Kilburn
<crusader.mike@gmail.com> wrote:
> Hi,
>
> How far optimizer could go when expanding inline functions? In
> particular in this code:
>
> inline void func(SmartPtr<MyClass> p)
> {
> if (smth) throw X;
> p->?; // use p
> }
>
> func(new MyClass(?));
>
> is it guaranteed that function arguments are constructed before first
> line of the inlined function is executed? I.e. is compiler allowed to
> postpone p's construction (given that if('smth') does not reference
> p)?
>
> Logical answer would be "no", but I'd like to understand why -- I
> could not find anything in standard that guarantees p's construction.
The answer really is no, because there is a sequence point between
evaluation of the function arguments and the function body (1.9.16). (and
inline/not-inline is not relevant here)
However, the compiler might actually eliminate/reorder some actions
because of the as-if rule. For example, if MyClass' constructor,
SmartPtr's constructor, operators new and delete all have provably no
visible effects, and smth is provably true, it might eleminate everything
and just throw X.
Regards
Jiri Palecek
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: wasti.redl@gmx.net
Date: Sat, 28 Feb 2009 12:28:50 CST Raw View
On Feb 27, 6:38 pm, Michael Kilburn <crusader.m...@gmail.com> wrote:
> Hi,
>
> How far optimizer could go when expanding inline functions? In
> particular in this code:
>
> inline void func(SmartPtr<MyClass> p)
> {
> if (smth) throw X;
> p->?; // use p
>
> }
>
> func(new MyClass(?));
>
> is it guaranteed that function arguments are constructed before first
> line of the inlined function is executed? I.e. is compiler allowed to
> postpone p's construction (given that if('smth') does not reference
> p)?
>
> Logical answer would be "no", but I'd like to understand why -- I
> could not find anything in standard that guarantees p's construction.
Inlining is an optimization, and therefore must not affect the
programs semantics. The visible behavior of the program must be the
same whether a function is inlined or not. So the question is just if
a function's arguments are guaranteed to be constructed before the
function is actually entered. The answer to this is yes. There's a
sequence point before function start, and another after function end.
Since argument construction is not part of the function, but of the
call site, it cannot be intermixed with the function code, if doing so
changes observable behavior.
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Greg Herlihy <greghe@mac.com>
Date: Sat, 28 Feb 2009 12:28:13 CST Raw View
On Feb 27, 9:38 am, Michael Kilburn <crusader.m...@gmail.com> wrote:
> inline void func(SmartPtr<MyClass> p)
> {
> if (smth) throw X;
> p->?; // use p
>
> }
>
> func(new MyClass(?));
>
> is it guaranteed that function arguments are constructed before first
> line of the inlined function is executed?
Yes.
> I.e. is compiler allowed to
> postpone p's construction (given that if('smth') does not reference
> p)?
No, because according to 5.2.2/8:
"... All side effects of argument expression evaluations take
effect before the function is entered."
So the compiler must ensure that the program initializes the SmartPtr
argument with a pointer to a newly-allocated Class object before
entering func(). Whether or not a particular function is declared as
inline - has no effect on this requirement.
Greg
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: James Kuyper <jameskuyper@verizon.net>
Date: Sat, 28 Feb 2009 12:30:38 CST Raw View
Michael Kilburn wrote:
> Hi,
>
> How far optimizer could go when expanding inline functions? In
> particular in this code:
>
> inline void func(SmartPtr<MyClass> p)
> {
> if (smth) throw X;
> p->?; // use p
> }
>
> func(new MyClass(?));
>
> is it guaranteed that function arguments are constructed before first
> line of the inlined function is executed? I.e. is compiler allowed to
> postpone p's construction (given that if('smth') does not reference
> p)?
>
> Logical answer would be "no", but I'd like to understand why -- I
> could not find anything in standard that guarantees p's construction.
The key thing to realize is that the 'inline' specifier only tells the
compiler that inline substitution of the function body is to be
preferred to the normal function call mechanism. The standard does not
give the implementation any freedom to make the inlined function behave
in any fashion that would not be permitted if the function were not inlined.
The standard specifies that "When a function is called, each parameter
(8.3.5) shall be initialized (8.5, 12.8, 12.1) with its corresponding
argument." (5.2.2p4), so construction of 'p' must be performed; whether
or not the function call is inlined is irrelevant.
The only thing that would allow the construction to be dropped would be
if dropping it would have no effect on the observable behavior of your
program. This is called the 'as-if' rule: the observable behavior of
your program must be exactly the same as-if the constructor had been
called, whether or not it actually was. But in that case, why should you
care whether it's been dropped?
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]