MISRA Discussion Forums

Full Version: For rule 5-2-12: replace "variable" with "value"?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Rule 5-2-12 is: "An identifier with array type passed as a function argument shall not decay to a pointer."

Why does the rule apply only to identifiers and function arguments? Example:

Code:
typedef char S[10];
S& f(void);
void g( const char * );
struct A { S m; };
A i(void);

void h(void) {
    g("foo");   // Compliant with the letter of 5-2-12.
    g(f());     // Compliant with the letter of 5-2-12.
    g(i().m);   // Compliant with the letter of 5-2-12.
}

Each of these calls would be in violation if the rule applied to values rather than variables.

Also the rationale says, "If a design requires arrays of different lengths, then a class should be used to encapsulate the array objects and so ensure that the dimensionality is maintained."

This question was motivated by a test case from one of our users:

Code:
#include

void dummy() {
    std::string s;
    s.assign("Hallo");
}

... against which PC-lint, in MISRA C++ mode, says that rule 5-2-12 has been violated. That's incorrect according to the letter of 5-2-12, but then, 5-2-12 is apparently violated in:

Code:
#include

void dummy() {
    const char h[] = "Hallo";
    std::string s;
    s.assign(h);
}

But given the rationale of the rule, it seems like MISRA probably wants to make an exception for the case of std::basic_string::assign(const char*) because it converts from a null-terminated character array to an object of class type that encapsulates the array value.

What about the restriction to cases of function arguments? Why does this restriction not apply to other contexts where there is a decay from array to pointer type? (Think of initialization/assignment in the context of a return statement, in the definition of a variable, in a curly-braced initializer, or in a men-initializer.)

If this rule applies only to function arguments but not initializers, then there is a funny difference in the treatment of initializers: If a class object is initialized by a constructor that takes a pointer, then this rule applies when the initializer value is initially of array type (because a constructor is a function and the initializer value is the argument to that function). But if you change the type of the declared object to a bare pointer type, the rule does not apply.
The conclusion in the question is correct, these various examples are permitted by the rule as it is currently worded. However, they were not intended to be permitted. A possible modification may be added to a TC to say "an argument of array type"
I have another question about the example code on page 83.

If
Code:
f2(a);// Non-compliant - Dimension "10" lost due to array to pointer conversion

is changed to

Code:
f2(&a[0]);

no more 5-2-12 violation is reported by our static analysis tool.
But my guess is, this is a loophole not intended by MISRA?

Thanks.
Your example is compliant f2 takes a pointer to int, &a[0] is a pointer to int - there is no decaying array
misra cpp Wrote:Your example is compliant f2 takes a pointer to int, &a[0] is a pointer to int - there is no decaying array
Ok, let me rephrase the question: is the code below fully compliant?

Code:
namespace nMISRA
{
  typedef unsigned char ui8;

  ui8 arr[10] = {0U};

  void f(ui8 p[])
  {
    p[10] = 1U;// in itself compliant with 5-0-15 but what about the combination of declaring arr as array and passing it as pointer to int?
  }

  void g(void)
  {
    f(&arr[0]);// in itself compliant with 5-2-12 but what about the combination of declaring arr as array and passing it as pointer to int?
  }
}
Your code does not violate 5-2-12, as you are passing an explicit pointer - its not an array identifier that has decayed to a pointer