This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Using pure and const attributes for Meyers' singleton


From: Martin Sebor [mailto:msebor@gmail.com] 
Sent: Mittwoch, 4. April 2018 17:28

> On 04/04/2018 07:25 AM, Antons.Jelkins@bmw.de wrote:
> > Hello,
> >
> > GCC has const and pure function attributes as described here:
> > https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes
> >
> > The attributes' specification is not as technical as the C++ standard, but their purpose seems to be to allow a
> > compiler to call functions annotated with const or pure less than a program code says. The specs also say that
> > such functions must not have any effects except their return value and the return value must depend only on
> > function arguments and/or (in case of "pure") global variables.
> >
> > Assume, there is such Meyers' singleton:
> >
> > class MyClass
> > {
> > public:
> >     MyClass();
> > };
> >
> > [[ gnu::const ]]
> > static const MyClass &myClass()
> > {
> >     static MyClass s_myClass;
> >     return s_myClass;
> > }
> >
> > Can const and pure attributes be used here? On the one hand, the singleton function does not have any observable
> > effects other than its return value and it always returns the same value. So it is completely safe to optimise away multiple
> > calls to this function. On the other hand, this function needs to construct the MyClass object on the first invocation.
> > This includes calling a MyClass constructor and setting an implicit is-initialised flag to true. It also must be thread-safe.
> > This could count as an effect besides the return value (although it is not visible from the outside).
>
> As you noted, the myClass() function has side-effects so declaring it const or pure violates the requirements in the manual.
> Issuing a warning for such a function is an improvement worth considering.

>From the description it is not really clear what "no effects" actually means. Here is a quote from another e-mail from the GCC
mailing list which implies "no observable effects":

| But if we are allowed to DCE a lazy_i call with unused result then it really is "pure". Basically with this property
| we consider the static variable it writes to as local, as it cannot be inspected in any other way than by calling
| the function or inspecting its return value.
https://gcc.gnu.org/ml/gcc/2012-10/msg00029.html

Would it be somehow possible to confirm or refute that GCC does not treat constructing a static local variable as an effect in
case of pure and/or const functions?

>
> > void doThis(const MyClass&);
> > void doThat(const MyClass&);
> >
> > void foo()
> > {
> >     doThis(myClass());
> >     doThat(myClass());
> > }
> >
> > GCC *does* optimise away the second call to myClass(). My question would be if this is an expected and desired
> > behaviour which I can rely on, or this is a coincidence?
>
> It's certainly no coincidence but I would hesitate to claim it's something to rely on for code correctness.  Going purely by what the manual says:
>
>    ...the presence of the attribute on a function declaration
>    allows GCC to emit more efficient code for some calls to
>    the function.
>
> it's clear that attribute is just a hint for the optimizer, not a requirement on the compiler to avoid emitting redundant calls to such functions.
>

Probably I have poorly expressed myself. I was asking if I can expect that this code will invoke myClass() once (in case the second call is
optimised away) or twice (if not), and during the first invocation it will properly construct the local static MyClass object? Or does this
code from compiler's point of view has an undefined behaviour and it can e.g. skip constructing MyClass and call doThis() with an unitialised
object?

> Martin
>
> >
> > Clang clearly treats this code as invalid, but they might change their behaviour if there is evidence that GCC implements a different rule:
> > https://bugs.llvm.org/show_bug.cgi?id=36750
> >
> > Regards,
> > Anton
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]