Topic: Defect Report: Inlining and observable behavior


Author: oporat@yahoo.com (Ofer Porat)
Date: Tue, 26 Jun 2007 17:51:15 GMT
Raw View
The C++ standard does not say whether inlining a function may alter the
observable behavior of a program.

Example:
==========
enum CatState
{
 Dead,
 Alive
};

volatile CatState SchroedingersCat = Alive;

struct T
{
 T() {}
 T(T const&) { SchroedingersCat = Dead; }
};

inline void g(T const& p)
{
    T q(p);
}

int main()
{
    g(T());
    return 0;
}
==========
If g() is not inlined, T's copy constructor must be called when
initializing q.  The copy may not be elided, since the temporary used
to initialize q is bound to the reference parameter p.

If g() is inlined, the compiler could conceivably eliminate the
single-use parameter p and transform main() to

int main()
{
    T q(T());
    return 0;
}

At this point, since the temporary is no longer bound to a reference,
the copy may be elided, and q can be value-initialized directly.  This
changes the observable behavior of the program.

The C++ standard does not say anything about what transformations are
allowed when inlining a function.  In particular, it doesn't say
whether inlining is allowed to change the observable behavior.


      ____________________________________________________________________________________
Luggage? GPS? Comic books?
Check out fitting gifts for grads at Yahoo! Search
http://search.yahoo.com/search?fr=oni_on_mail&p=graduation+gifts&cs=bz

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: hyrosen@mail.com (Hyman Rosen)
Date: Tue, 26 Jun 2007 19:53:37 GMT
Raw View
Ofer Porat wrote:
> The C++ standard does not say whether inlining a function may alter the
> observable behavior of a program.

And therefore it may not. The only difference between an inline
function and a plain one is that an inline function must be defined
in every compilation unit in which it is called.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: ricecake@gehennom.invalid (Marcus Kwok)
Date: Tue, 26 Jun 2007 19:54:58 GMT
Raw View
Ofer Porat <oporat@yahoo.com> wrote:
> The C++ standard does not say whether inlining a function may alter the
> observable behavior of a program.
>
[example snipped]
>
> At this point, since the temporary is no longer bound to a reference,
> the copy may be elided, and q can be value-initialized directly.  This
> changes the observable behavior of the program.
>
> The C++ standard does not say anything about what transformations are
> allowed when inlining a function.  In particular, it doesn't say
> whether inlining is allowed to change the observable behavior.

However, I'm pretty sure it specifically states that the copy
constructor elision is special, in that it may be elided even if it has
side effects (I can't cite since I don't have access to the Standard at
this time, but I have seen this mentioned multiple times on the various
C++ newsgroups).

Therefore, a copy constructor should only be doing things that
copy-construct an object, and should not depend on any side effects
occurring.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Wed, 27 Jun 2007 10:02:54 CST
Raw View
On Jun 26, 7:51 pm, opo...@yahoo.com (Ofer Porat) wrote:
> The C++ standard does not say whether inlining a function may alter the
> observable behavior of a program.

It does say that inlining does not affect the semantics of a
program.  Inlined or not, the possible legal observable
behaviors are the same.

> Example:
> ==========
> enum CatState
> {
>         Dead,
>         Alive
> };

> volatile CatState SchroedingersCat = Alive;

> struct T
> {
>         T() {}
>         T(T const&) { SchroedingersCat = Dead; }
> };

> inline void g(T const& p)
> {
>     T q(p);
> }

> int main()
> {
>     g(T());
>     return 0;}

> ==========
> If g() is not inlined, T's copy constructor must be called when
> initializing q.

No.  The standard explicitly gives the compiler the right to
elide the copy constructor in this case.  If calling the
copy constructor changes the observable behavior of the program,
there are two different possible legal observable behaviors.
Which one you get is unspecified.

(In the above, of course, nothing has any effect on observable
behaviour, and a good compiler will probably eliminate the call
to g completely, along with any construction of T.  Regardless
of whether g is inlined or not.)

> The copy may not be elided, since the temporary used
> to initialize q is bound to the reference parameter p.

So.  The standard says that it can be elided.  I think the most
recent draft even says that there may not be a copy.

> If g() is inlined, the compiler could conceivably eliminate the
> single-use parameter p and transform main() to

> int main()
> {
>     T q(T());
>     return 0;
> }

> At this point, since the temporary is no longer bound to a reference,
> the copy may be elided, and q can be value-initialized directly.  This
> changes the observable behavior of the program.

> The C++ standard does not say anything about what transformations are
> allowed when inlining a function.  In particular, it doesn't say
> whether inlining is allowed to change the observable behavior.

Inlining has no effect on the set of allowed observable
behaviors.  In this case, the only observable behavior that the
program has is to return 0.  And the program is simple enough
that I expect most compilers will not generate anything else, at
least when optimization is turned on.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: Martin Bonner <martinfrompi@yahoo.co.uk>
Date: Thu, 28 Jun 2007 11:23:12 CST
Raw View
On Jun 27, 5:02 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Jun 26, 7:51 pm, opo...@yahoo.com (Ofer Porat) wrote:
>
> > The C++ standard does not say whether inlining a function may alter the
> > observable behavior of a program.
>
> > Example:
> > ==========
> > enum CatState
> > {
> >         Dead,
> >         Alive
> > };
> > volatile CatState SchroedingersCat = Alive;
> > struct T
> > {
> >         T() {}
> >         T(T const&) { SchroedingersCat = Dead; }
> > };
> > inline void g(T const& p)
> > {
> >     T q(p);
> > }
> > int main()
> > {
> >     g(T());
> >     return 0;}
> > ==========
> > If g() is not inlined, T's copy constructor must be called when
> > initializing q.
>

> (In the above, of course, nothing has any effect on observable
> behaviour,

Not so.  SchroedingersCat is declared volatile; as such an assignment
to it is "observable behaviour" (section 1.9/6).

But I agree that whether the observable behaviour occurs is
implementation defined/dependant.

>
> Inlining has no effect on the set of allowed observable
> behaviors.  In this case, the only observable behavior that the
> program has is to return 0.  And the program is simple enough
> that I expect most compilers will not generate anything else, at
> least when optimization is turned on.
>
> --
> James Kanze (GABI Software)             email:james.ka...@gmail.com
> Conseils en informatique orient   e objet/
>                    Beratung in objektorientierter Datenverarbeitung
> 9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]



---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: James Kanze <james.kanze@gmail.com>
Date: Mon, 2 Jul 2007 23:12:53 CST
Raw View
On Jun 26, 9:53 pm, hyro...@mail.com (Hyman Rosen) wrote:
> Ofer Porat wrote:
> > The C++ standard does not say whether inlining a function may alter the
> > observable behavior of a program.

> And therefore it may not. The only difference between an inline
> function and a plain one is that an inline function must be defined
> in every compilation unit in which it is called.

For any given program, the standard specifies a set of possible
observable behaviors.  A compiler could choose a different
member of the set depending on whether it inlined a function or
not.  Just as it could choose randomly.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ 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.comeaucomputing.com/csc/faq.html                      ]