Question about an example from rule 9-3-1

Moderators: david ward, misra cpp

cxlin
Posts: 6
Joined: Tue May 12, 2015 1:24 am
Company: Red Lizard Software

Question about an example from rule 9-3-1

Postby cxlin » Fri Apr 07, 2017 6:50 am

Hi MISRA,

I have a question about the following example from rule 9-3-1:

Code: Select all

class C {
public:
  C ( int &b_ ) : b( b_ ) { }

  int *getB () const
  {
    return &b;  // Non-compliant
  }
private:
  int &b;
}

Here `getB` actually returns a pointer to the object that `b` referenced, not the member `b` itself. And that object doesn't seem to satisfy the definition of "class data" by 1) it's not non-staitc member data, and 2) it's not a resource acquired in the constructor or released in the destructor. So I'm not sure why this is a Non-compliant case. Could you help to clarify a bit? Thanks!

dg1980
Posts: 107
Joined: Wed Apr 27, 2016 2:33 pm
Company: Elektrobit Automotive GmbH

Re: Question about an example from rule 9-3-1

Postby dg1980 » Fri Apr 07, 2017 8:23 am

Maybe this extended and commented sample answers your question:

Code: Select all

#include <stdint.h>

namespace nMISRA
{
  class C {
  public:
    C ( int32_t &b_ ) : b( b_ ) { }

    int32_t *getB () const
    {
      return &b;  // Non-compliant
    }
    int32_t getState(void) const{return b;}
  private:
    int32_t &b;
  };
}

int32_t main(void)
{
  int32_t ret = 0;
  int32_t state = 0;
  nMISRA::C c(state);
  *c.getB() = 1;// const member changing the state of the object, triggering error condition below
  if (c.getState() != 0)
  {
    ret = -1;// error
  }
  return ret;
}

cxlin
Posts: 6
Joined: Tue May 12, 2015 1:24 am
Company: Red Lizard Software

Re: Question about an example from rule 9-3-1

Postby cxlin » Fri Apr 07, 2017 9:45 am

dg1980 wrote:Maybe this extended and commented sample answers your question:

Code: Select all

int32_t main(void)
{
  int32_t ret = 0;
  int32_t state = 0;
  nMISRA::C c(state);
  *c.getB() = 1;// const member changing the state of the object, triggering error condition below
  if (c.getState() != 0)
  {
    ret = -1;// error
  }
  return ret;
}


Well, `state` is not part of the object `c` (and likely not "class data"). It doesn't make much sense if this rule is to enforce that `getB` only return a const handler of `state`, because `state` is already in scope and could be modified without calling `getB`!

Code: Select all

  int32_t state = 0;
  nMISRA::C c(state);
  state = 1;
  if (c.getState() != 0)
  ...


So I don't think the original example follows the rationale of the rule and thus the original question.

cxlin
Posts: 6
Joined: Tue May 12, 2015 1:24 am
Company: Red Lizard Software

Re: Question about an example from rule 9-3-1

Postby cxlin » Fri Apr 07, 2017 9:45 am

dg1980 wrote:Maybe this extended and commented sample answers your question:

Code: Select all

int32_t main(void)
{
  int32_t ret = 0;
  int32_t state = 0;
  nMISRA::C c(state);
  *c.getB() = 1;// const member changing the state of the object, triggering error condition below
  if (c.getState() != 0)
  {
    ret = -1;// error
  }
  return ret;
}


Well, `state` is not part of the object `c` (and likely not "class data"). It doesn't make much sense if this rule is to enforce that `getB` only return a const handler of `state`, because `state` is already in scope and could be modified without calling `getB`!

Code: Select all

  int32_t state = 0;
  nMISRA::C c(state);
  state = 1;
  if (c.getState() != 0)
  ...


So I don't think the original example follows the rationale of the rule and thus the original question.

dg1980
Posts: 107
Joined: Wed Apr 27, 2016 2:33 pm
Company: Elektrobit Automotive GmbH

Re: Question about an example from rule 9-3-1

Postby dg1980 » Fri Apr 07, 2017 10:11 am

As soon as you store a reference, it becomes class data.
I slightly reworked the example, to make it even more obvious what evil code you could write, if this was not treated a violation of 9-3-1:

Code: Select all

#include <stdint.h>

namespace nMISRA
{
  class C {
  public:
    C ( int32_t &b_ ) : b( b_ ) { }

    int32_t *getB () const
    {
      return &b;  // Non-compliant
    }
    int32_t getState(void) const{return b;}
  private:
    int32_t &b;
  };

  void foo(const C& rhs, int32_t s)
  {
    *rhs.getB() = 1;// !!!wow, a const ref and a const member change the state of the object without even knowing the variable defined in main!!!
  }
}

int32_t main(void)
{
  int32_t ret = 0;
  int32_t state = 0;
  nMISRA::C c(state);
 
  nMISRA::foo(c, 1);
  if (c.getState() != 0)
    ret = -1;// error
  return ret;
}

cxlin
Posts: 6
Joined: Tue May 12, 2015 1:24 am
Company: Red Lizard Software

Re: Question about an example from rule 9-3-1

Postby cxlin » Fri Apr 07, 2017 11:59 am

dg1980 wrote:As soon as you store a reference, it becomes class data.


To me that's not clear from the definition of "class data" (as mentioned in the original post). And this is exactly the question I'm asking MISRA to confirm.

The same goes with a resource that's not allocated by the constructor or released by the destructor, but pointed to by a pointer member.

Note the definition of "class data" actually made clear that static members are not "class data", and in the example the resource reference by `b` could be shared by multiple objects and acts basically the same as a static member.

I slightly reworked the example, to make it even more obvious what evil code you could write, if this was not treated a violation of 9-3-1:


The evilness of your code does not come from not following 9-3-1, but from the fact that a member referencing a shared object (with automatic storage). Removing `const` from `getB` and some other functions will make the code 9-3-1 compliant (under your interpretation) but doesn't really make it less evil.

misra cpp
Posts: 136
Joined: Mon Jun 02, 2008 1:55 pm
Company: MISRA

Re: Question about an example from rule 9-3-1

Postby misra cpp » Mon Jul 10, 2017 11:49 am

The code doesn't violate the rule, as the value returned by the function does not allow any class member to be modified
Posted by and on behalf of
the MISRA C++ Working Group


Return to “6.9 Classes (C++)”

Who is online

Users browsing this forum: No registered users and 1 guest