2

The following code violates the MISRA C++ rule 5-0-15: Array indexing shall be the only form of pointer arithmetic.

(1)

void doSomething(const uint8_t *&ptr, size_t num) {
  ptr += num;
}

Incrementing any pointer also violates the above rule:

(2)

const uint8_t *ptr = ... ;
*ptr++;

I found a very similar question here, but there the questioner uses arrays. I use pointers.

Is there an alternative notation or other method to add numbers to (1)/ increment (2) pointers to get around this violation?

KplnMoon
  • 151
  • 1
  • 10
  • 2
    The point of that rule is to disallow you from doing things like incrementing pointers. You should [edit] your question to describe what you’re trying to do that you feel requires that, and can’t be done with the array indexing operator. – Sneftel May 14 '22 at 12:26
  • @AdrianMole Thanks I think i had a brain lapse for a second – Alexander May 14 '22 at 12:51
  • Did you read the notes below the rule? It explains what to use. – KamilCuk May 14 '22 at 12:54
  • The other method is to loudly complain to your manager to have this rule disabled in the compliance checker. It is actively harmful. For example, if Alex Stepanov were subject to this rule, we would never have STL. – n. m. could be an AI May 14 '22 at 12:57
  • 1
    @n.1.8e9-where's-my-sharem. You miss the point of what guidelines or standards like MISRA are about - they are not a blunt tool that prevents library developers doing anything. Alex could have documented a justification for an exception to MISRA rules and included it in documentation with the STL. The same goes (more recently) for developers of implementations of the C++ standard library. System developers using that library under MISRA guidelines need to justify and seek approval of any exemption, and can base their case on appropriate evidence provided by the library developer. – Peter May 14 '22 at 13:27
  • @Sneftel I would use the array indexing operator if it will solve the problem. I tried e.g. ptr[1] instead of *(ptr++), but that was not the solution. Do you have another idea? – KplnMoon May 14 '22 at 13:42
  • @KamilCuk Yes, I have. Unfortunately, that did not help me. – KplnMoon May 14 '22 at 13:43
  • @Peter Every single STL algorithm uses iterator arithmetic, which is a generalisation of pointer arithmetic and reduces to pointer arithmetic when used on C-style arrays. If I had to fill out paperwork in order to either use `std::sort` or create a similar algorithm, I would probably just quit. There are saner places to work out there. – n. m. could be an AI May 14 '22 at 13:44
  • @n.1.8e9-where's-my-sharem. If you were using STL (or any library) when developing software that, if it malfunctions, can kill people - then you are required to justify your choice and convince someone (often a more senior person who must convince a regulator that the system is safe to use) to approve that choice. If you are developing software for a system that can fail without such significant consequences, you probably wouldn't need to seek that approval. And probably wouldn't be using MISRA either - because it is not geared to you – Peter May 14 '22 at 13:54
  • @Peter If I ever find myself in such situation, I'll quit faster than you can say "you are required to justify your choice". I don't think C++ is usable for developing life-critical applications in the first place, with or without MISRA. Regardless of any live-or-death situation, I just don't believe that avoiding programming techniques popularised by STL adds any level of safety to C++. I believe the opposite is true. STL programming paradigm is tried and true. Techniques one is forced to develop on the spot in order to appease the spirits of MISRA are anything but. – n. m. could be an AI May 14 '22 at 14:34
  • `es, I have. Unfortunately, that did not help m` that is something odd, there's examples, like `++iter; // Compliant by exception` and `p4 = &p2[ 5 ]; // Compliant`. – KamilCuk May 14 '22 at 16:23
  • 1
    @n.1.8e9-where's-my-sharem. C++ has been used for high-criticality applications (like safety related) for some time - the guidelines like those of MISRA (or alternatives) are relevant to doing that effectively. Your comments make it quite clear that you have no interest in doing that type of software development, so why are you getting in an uproar over requirements that wouldn't even be relevant to the type of development you do? – Peter May 15 '22 at 03:51
  • Looking at the answer to this question doesn't instill any confidence in relevance of MISRA. If all of its guidelines are as trivial to work around as the answer suggests, then they are security theater. Anyway, I'll quit ranting, sorry about that. – n. m. could be an AI May 15 '22 at 04:57
  • 1
    @n.1.8e9-where's-my-sharem. - the DoD are satisfied that MISRA C/C++ makes C/C++ usable... to the extent that the previous mandate to use ADA was relaxed to allow MISRA - including on the Joint Strike Fighter (whose coding guidelines are based on MISRA). – Andrew May 15 '22 at 08:47
  • @Andrew - Actually, it appears the other way around. The first release of MISRA C++ in 2008 (according to attributions it provides) drew on a preceding version of MISRA C, JSF++ (REV C dated 2005), and HICPP (a high integrity coding standard for C++ from a UK company named PRQA). US DoD cancelled MIL-STD-1815A (the current specification of ADA at that time) without replacement in 1997 (before the first C++ standard was ratified in 1998) and the mandate to use ADA was cancelled in 2004. It's not clear, but quite possible, that decision was informed by evolving coding standards for C++ – Peter May 15 '22 at 13:12
  • 1
    If you read carefully, Peter, I just said JSF was based on MISRA not MISRA C++ (actually MISRA C:2004)... but let's not split hairs - the point to n was that MISRA C/C++ are **very** relevant, especially in the critical systems domain. – Andrew May 15 '22 at 16:44
  • Personally I would not recommend using MISRA C:2004, MISRA C++:2008 or C++ for new design of safety-related software. Also the JSF documents were always kind of strange... they start with listing a whole lot of sound advice (JSF C++:2005 chapter 3) and literally everything said in that initial good advice chapter suggests that C++ is an entirely unsuitable language. And this was before the whole C++11 and beyond circus started. – Lundin May 16 '22 at 08:31
  • @Lundin Would you roll your own guidelines? How would you certify those? Or would you use other languages (Ada, Rust, C, Ocaml, Idris, Agda, F*, Lean, Pascal) altogether? The circus you mentioned would be the SEI CERT C++ rules?https://wiki.sei.cmu.edu/confluence/?%20contentId=88046682#content/view/88046682 They look quite reasonable. – Sebastian May 16 '22 at 09:20
  • @Sebastian I would ideally use MISRA C:2012. Funny thing since I'm still mostly stuck in MISRA C:2004 myself, because of tool license reasons. The circus I mentioned would be the C++ standard going haywire with new features from 2011 and beyond. Standard C has around ~10 pages of listed UB and maybe 30-40 pages of listed poorly-defined behavior. Standard C++2x will have somewhere around 1000 pages of it, though the chose not to include a (brief) summary of all UB in the C++ standard, or it would completely dominate the document. – Lundin May 16 '22 at 09:26
  • @Lundin So one could create checklists for safety critical code review out of the 1000 pages? ;-) you mean those? https://github.com/ISO-IEC-JTC1-SC22-WG23-CPP/wg23-tr24772-10-public or the standard itself? – Sebastian May 16 '22 at 09:34
  • @Sebastian Using C++ to achieve safety (*SIL) certification is kind of like using nitroglycerine as your means to achieve explosive atmosphere certification. I don't even think there exists a single human being who _knows_ all the UB in C++, let alone how to work around it. C++ has become an experimental language. – Lundin May 16 '22 at 09:36
  • @Lundin No one is using C++ as a means to achieve safety certification, ever. People might be using C++ as a means to have the code out of the gate quickly, and trying to achieve safety certification despite that (which is IMO a lost game but I'm not judging). – n. m. could be an AI May 19 '22 at 12:57

2 Answers2

2

Array indexing

So use array indexing.

void doSomething(const uint8_t ptr[], size_t num) {
     const uint8_t *ptr2 = &ptr[num];
}

Incrementing any pointer

Increment and decrement operators can be used by exception. Doing dereference with incrementing is invalid. There have to be two expressions.

const uint8_t *ptr = somearray;
++ptr;
uint8_t val = *ptr;
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • The 1st part solves the problem, but unfortunately violates other guidelines. But that's enough for me for now. Thanks a lot! – KplnMoon May 15 '22 at 13:54
2

The "array indexing shall be the only form of pointer arithmetic" rule was inherited from MISRA C:2004 and there were discussions early on about whether the rule made sense or not. The rationale behind the rule was to prevent *(arr+i) style over arr[i] style and I don't think anyone is questioning that the latter is more readable and therefore preferred.

However, the examples in the MISRA C:2004 document were confusing - it wouldn't allow array style indexing on variables declared as pointers. But obviously in case of functions, it doesn't matter if we declare something as void func (int* ptr) or void func (int ptr[]) because these are 100% equivalent thanks to the parameter adjustment rules of C. In fact the []operator can only be used with pointer operands as explained here: Do pointers support "array style indexing"? So this rule lead to a lot of false positives.

This is one of many things that were fixed in MISRA C:2012, where rule 18.4 is focusing on the pointer artithmetic itself rather than how something was declared. MISRA C:2004 and MISRA C++:2008 will still have the old wording and examples though, so if you are using those, you should take the rule with a grain of salt.

In your specific case, using const uint8_t *&ptr vs const uint8_t& ptr[] doesn't matter. ptr += num; is the questionable part.

Unrelated to the rule, having a pointer to an array of references is pretty fishy as well and would need to be reviewed, in case it is possible to use less complex alternatives.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • There are no arrays of references or pointers to references in C++. `const uint8_t *&ptr` is a reference to a pointer. You can have a reference to an array `uint8_t (&a)[]` but of course you cannot perform `+=` on an array. – n. m. could be an AI May 19 '22 at 13:01