Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Would strlen() be possible with Rule 17.4?
#1
Small function I am trying to write is to take a string literal, and copy [part of] it to an array.

The array is fine, declared as an array and only accessed using indexing. But I cannot figure out how to search the string for particular sequences of char.

It's a string literal, so passed into the function as
foo("Hello World");
So the parameter is const char_t *. So how could I do anything with that, even find the length of it? I can't step the pointer through it, I can't even access it by index. Is such a thing as a string literal even legal?

void foo(const Octet *p)
{
/* ...Now what? p[n] is not legal because Octet * is not an array type,
and p++ would be a definite no-no.
*/
}

If I declared it as
void foo(const char_t c[])
would that be legitimate? It's legal C, I think, and it looks like an array declaration, but I don't see the difference between that and the previous. I can call it with
char_t *p;
...
foo(p);
or even
foo(NULL);
without a compiler warning (using gcc -ansi -pedantic -Wall; I'm sure PC-Lint would notice, but I don't have it here at home). So if the previous declaration was illegal, would this be also?

If I understand correctly, then it seems to me that even a simple function like strlen() could not be written, in a way that would be compliant. Is that, in fact, the case?

Frank
<t></t>
Reply
#2
The purpose of Rule 17.4 is to limit the general use of pointers in order to make code easier to review and analyse. If an object is declared with a pointer type, the assumption is that it is being used only to access a single object or array element. If access to more than one element is required then the object should be declared with an array type instead.

When a parameter is declared with an array type, it is treated as if it were a pointer to the first element of the array instead. However, for the purposes of Rule 17.4, parameters declared with an array type are treated as arrays. It is therefore only possible to perform arithmetic and array indexing on an object only when it is declared as an array.

An important consideration about Rule 17.4 is that it looks only at the form of the declaration of a pointer or array object and does not consider the type of the underlying object to which the pointer or array points.

Therefore it is possible to pass either a pointer or an array as an argument to a function that is expecting an array parameter. In this way, it would be possible to write strlen as:

Code:
size_t strlen (const char s[ ])
{
  size_t len = 0;

  while (s[len] != '\0') {
    ++len;
  }

  return (len);
}
It would be possible to pass any "array of char" or "pointer to char" to this version of strlen() and comply with Rule 17.4.

Of course, the standard declares strlen as:

Code:
size_t strlen (const char *s);
so the implementation using an array is not permitted and it is not possible to write the standard strlen without deviating Rule 17.4. While this is unfortunate, it is felt that the benefits of applying Rule 17.4 to application code outweigh the inconvenience of having to use deviations for a standard library.
Posted by and on behalf of the MISRA C Working Group
Reply
#3
Thank you! That is a big relief.

I was beginning to think that you had to operate on the array itself, rather than passing it to a function. Realising that [] and * are equivalent in an argument list, I though both would be outlawed, and could not see a way to proceed.

I'm not so worried about a compliant strlen() not matching the ANSI library standard prototype. I used it as an example because everyone knows how a simple one works and what it does. Now you have shown me a legal way to do that, I can use the same on my own code.

* fpeelo happy now :)

Frank
<t></t>
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)