MISRA Discussion Forums

Full Version: 5-2-12 - Does the rule apply for braced-init-list arg to initializer_list parameter?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,

Rule 5-2-12 covers array to pointer decay in a function call:
Quote:Rule 5-2-12 (required, implementation, automated) An identifier with array type passed as a function argument shall not decay to a pointer.

This rule has been brought over to the AUTOSAR C++14 guidelines in verbatim (as M5-2-12), where it applies to more modern C++.

Now, an object of type std::initializer_list<E> (for some type E) is, as per [dcl.init.list]/5 (N4140/C++14), defined to be constructible from a braced-init-list as follows:

Quote:An object of type std::initializer_list<E> is constructed from an initializer list as if the implementation allocated a temporary array of N elements of type const E, where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list<E> object is constructed to refer to that array.

Some compilers (correctly within their implementation freedom) implements the constructor of their std::initializer_list class template with two arguments: a begin iterator for the "as if an array" argument, and a size of the list (automagically provided). 

Our static analyzer for AUTOSAR C++14 (whilst noting that this is a pre-C++11 rule) uses this to argue that any occasion where a braced-init-list is used as argument to a (compatible) function parameter that is a specialization of std::initializer_list is a violation of M5-2-12, essentially meaning we can neither use any of the std::initializer_list constructors from our in-house container classes, nor act as clients for many of the standard library's container classes (say under the assumption that we have an certified subset STL available):
Code:
#include <initializer_list>
#include <vector>

namespace rule_m5_2_12
{

/// @brief Docs.
template <typename ScalarT, std::int32_t N>
class StaticVector final
{
public:
    /// @brief Docs.
    /// @param list Docs.
    StaticVector(std::initializer_list<ScalarT> const list) noexcept : data_{} {}
private:
    /// Docs.
    ScalarT data_[N];
};

inline void f()
{
    constexpr std::int32_t kSize{3};

    // "Array type is used as a pointer type argument in the function call."
    auto const a = StaticVector<std::int32_t, kSize>{1, 2, 3};  // M5-2-12 violation
    auto const b = std::vector<std::int32_t>({1, 2, 3});        // M5-2-12 violation

    // ...
}

}  // namespace rule_m5_2_12

Is the intent that Rule M5-2-12 (in the modern C++ world) should prohibit any client side (braced-init-list argument) usage of std::initializer_list<E> function parameters?

Thanks!
When the MISRA rule was written initializer_lists had not been defined, so were not considered by the rule. It was adopted by Autosar unmodified.

The view of the committee is that use of initializer_lists should be compliant with this rule, even if it can be assumed that it is implemented with an array decay.