Main Content

MISRA C++:2023 Rule 6.8.4

Member functions returning references to their object should be ref-qualified appropriately

Since R2024b

Description

Rule Definition

Member functions returning references to their object should be ref-qualified appropriately.

Rationale

A member function that returns a reference or pointer to a temporary object (rvalue) or one of its subobjects results in a dangling reference or pointer when that object goes out of scope.

You use ref-qualifiers & and && on member functions to specify whether the function is invoked on an lvalue reference (&) or on an rvalue reference (&&). For example, in this code snippet, the member function func() is ref-qualified so that the correct version is called on the lvalue object myObj and on a temporary rvalue object when calling Foo().func().

class Foo
{
public:
    void func() &
    { // lvalue ref qualified
        std::cout << "Called with lvalue\n";
    }
    void func() &&
    { // rvalue ref qualified
        std::cout << "Called with rvalue\n";
    }
};

void otherFunc()
{
    Foo myObj;    // lvalue object
    myObj.func(); // Prints "Called with lvalue"
    Foo().func();   // Prints "Called with rvalue"
}
To avoid calling a member function on a temporary object, do one of the following:

  • Declare a function that is non-const and lvalue ref-qualified. For example

    int &func() & 
    { 
        // ...
    }

  • If you declare member function as const and lvalue-ref-qualifed, declare an rvalue-ref-qualified overload with the same signature. Note that an rvalue-ref-qualified member function should not return a reference or pointer to its object or one of its subobjects because such a function binds only to temporary objects. For example

    class Foo
    {
    public:
        Foo const *funcHasOverload(const int idx) const &
        {
            return this;
        }
        Foo const *funcHasOverload(const int idx2) && = delete;
    };

Polyspace Implementation

The coding rule checker reports a violation if a member function returns a direct reference or pointer to this or one of its subobjects, and one of these is true:

  • The function is not ref-qualified.

  • The function is const qualified and lvalue-ref-qualified but there is no rvalue-ref-qualified overload with the same signature.

  • The function is rvalue-ref-qualified.

If a member function returns an indirect reference to a temporary object after the object goes out of scope, Polyspace reports a violation of rule MISRA C++:2023 Rule 6.8.1.

Polyspace does not report a violation on defaulted assignment operators, which are excluded from this rule because they do not have a definition.

Troubleshooting

If you expect a rule violation but Polyspace® does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

#include <iostream>

class myClass
{
public:
    int value;

    myClass(int val) : value(val) {}

    myClass *fncNotRefQualified() // Noncompliant
    { 
        return this;
    }

    const myClass *fncMissingOverload() const & // Noncompliant
    { 
        return this;
    }

    // Uncomment rvalue-ref-qualified function to make previous call to 
    // fncMissingOverload compliant
    //  const myClass* fncMissingOverload() const && = delete;

    myClass &fncRValueQualified() && // Noncompliant
    { 
        return *this;
    }
};

In this example, Polyspace reports a violation for these member functions of the class myClass:

  • fncNotRefQualified() — This function returns a pointer to the current instance of myClass. Because the function is not ref-qualified, it can be called on a temporary object, which would result in a dangling pointer once the object goes out of scope.

  • fncMissingOverload() — This function also returns a pointer to the current instance of myClass. The function is const qualified and lvalue-ref-qualified and can bind to a temporary object.

    If you uncomment the rvalue-ref-qualified declaration of fncMissingOverload() and rerun the analysis, the first declaration of fncMissingOverload becomes compliant because a temporary object binds to the rvalue-ref-qualified function after overload resolution.

  • fncRValueQualified() — This function returns a reference to the current instance of myClass. Because the function is rvalue-ref-qualified, it binds only to temporary objects and results in a dangling reference when the object goes out of scope.

Check Information

Group: Basic concepts
Category: Advisory

Version History

Introduced in R2024b