Rule A6-2-2 (required, implementation, automated)

Expression statements shall not be explicit calls to constructors of temporary objects only.

Rationale

The developer’s intention might have been to define an unnamed local variable that would live until the end of the scope to implement the RAII pattern (Resource Acquisition Is Initialization). But as there are no unnamed variables in C++, it is in fact only creating a temporary object that gets destroyed again at the end of the full expression.

Example

// $Id: A6-2-2.cpp 326655 2018-07-20 14:58:55Z christof.meerwald $

#include <cstdint>
#include <fstream>
#include <mutex>

class A
{
public:
void SetValue1(std::int32_t value)
{
std::lock_guard<std::mutex> {m_mtx}; // Non-compliant: temporary object
// Assignment to m_value is not protected by lock
m_value = value;
}

void SetValue2(std::int32_t value)
{
std::lock_guard<std::mutex> guard{m_mtx}; // Compliant: local variable m_value = value;

}

private:
mutable std::mutex m_mtx;
std::int32_t m_value;
};

void Print(std::string const & fname, std::string const & s)
{
// Compliant: Not only constructing a temporary object
std::ofstream{fname}.write(s.c_str(), s.length());
}

See also

C++ Core Guidelines [11]: ES.84: Don’t (try to) declare a local variable with no name C++ Core Guidelines [11]: CP.44: Remember to name your lock_guards and unique_locks Rule M6-2-2 (required, implementation, partially automated) Floatingpoint expressions shall not be directly or indirectly tested for equality or inequality. See MISRA C++ 2008 [7]