Pointer to Array of Bytes

a 夏天 提交于 2019-12-06 13:47:27

In void Foo(uint8_t (*pu8Buffer)[], uint16_t u16Len), pu8Buffer is a pointer to an (incomplete) array of uint8_t. pu8Buffer has an incomplete type; it is a pointer to an array whose size is unknown. It may not be used in expressions where the size is required (such as pointer arithmetic; pu8Buffer+1 is not allowed).

Then *pu8Buffer is an array whose size is unknown. Since it is an array, it is automatically converted in most situations to a pointer to its first element. Thus, *pu8Buffer becomes a pointer to the first uint8_t of the array. The type of the converted *pu8Buffer is complete; it is a pointer to uint8_t, so it may be used in address arithmetic; *(*pu8Buffer + 1), (*pu8Buffer)[1], and 1[*pu8Buffer] are all valid expressions for the uint8_t one beyond *pu8Buffer.

I take it you are referring to MISRA-C:2004 rule 17.4 (or 2012 rule 18.4). Even someone like me who is a fan of MISRA finds this rule to be complete nonsense. The rationale for the rule is this (MISRA-C:2012 18.4):

"Array indexing using the array subscript syntax, ptr[expr], is the preferred form of pointer arithmetic because it is often clearer and hence less error prone than pointer manipulation. Any explicitly calculated pointer value has the potential to access unintended or invalid memory addresses. Such behavior is also possible with array indexing, but the subscript syntax may ease the task of manual review.

Pointer arithmetic in C can be confusing to the novice The expression ptr+1 may be mistakenly interpreted as the addition of 1 to the address held in ptr. In fact the new memory address depends on the size in bytes of the pointer's target. This misunderstanding can lead to unexpected behaviour if sizeof is applied incorrectly."

So it all boils down to MISRA worrying about beginner programmers confusing ptr+1 to have the outcome we would have when writing (uint8_t*)ptr + 1. The solution, in my opinion, is to educate the novice programmers, rather than to restrict the professional ones (but then if you hire novice programmers to write safety-critical software with MISRA compliance, understanding pointer arithmetic is probably the least of your problems anyhow).

Solve this by writing a permanent deviation from this rule!


If you for reasons unknown don't want to deviate, but to make your current code MISRA compliant, simply rewrite the function as

void Foo(uint8_t pu8Buffer[], uint16_t u16Len)

and then replace all pointer arithmetic with pu8Buffer[something]. Then suddenly the code is 100% MISRA compatible according to the MISRA:2004 exemplar suite. And it is also 100% functionally equivalent to what you already have.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!