3

This is the synopsis for strspn:

#include <string.h>

size_t strspn(const char *s1, const char *s2);

This is the description and return value for POSIX.1-2001:

The strspn() function shall compute the length (in bytes) of the maximum initial segment of the string pointed to by s1 which consists entirely of bytes from the string pointed to by s2.

The strspn() function shall return the length of s1; no return value is reserved to indicate an error.

This is (almost) the same from POSIX.1-2017:

The strspn() function shall compute the length (in bytes) of the maximum initial segment of the string pointed to by s1 which consists entirely of bytes from the string pointed to by s2.

The strspn() function shall return the computed length; no return value is reserved to indicate an error.

Is it possible for an implementation of strspn to be compliant with both POSIX.1-2001 and POSIX.1-2017? How?

S.S. Anne
  • 15,171
  • 8
  • 38
  • 76

2 Answers2

8

This is a bug in POSIX.1-2001.

As the POSIX description of strspn says:

The functionality described on this reference page is aligned with the ISO C standard. Any conflict between the requirements described here and the ISO C standard is unintentional. This volume of IEEE Std 1003.1-2001 defers to the ISO C standard.

And the C standard (ISO 9899:1999, 7.21.5.6 The strspn function) clearly says:

The strspn function returns the length of the segment.

Newer editions of POSIX fixed the wording to make it say the same thing as the C standard, which is what was always intended. (It was apparently noticed and changed in 2006; see https://www.opengroup.org/austin/docs/austin_330.txt. The current version of strspn in POSIX refers to this (rather cryptically) as "SD5-XSH-ERN-182 is applied" in the CHANGE HISTORY section.)

As POSIX says it "defers to the ISO C standard", I believe compliant implementations must follow the C standard when there is a conflict, such as in this case.

melpomene
  • 84,125
  • 8
  • 85
  • 148
  • 2
    The 1997 POSIX specification for [`strspn()`](http://pubs.opengroup.org/onlinepubs/7990989775/xsh/strspn.html) doesn't have the "defer to C standard" disclaimer on the same page — but does have the erroneous wording. The online C11 specification for [`strspn()`](http://port70.net/~nsz/c/c11/n1570.html#7.24.5.6) is from the N1570 draft of the standard. The C99 equivalent is [`strspn()`](http://port70.net/~nsz/c/c99/n1256.html#7.21.5.6), and that's from the N1256 draft of the standard. – Jonathan Leffler Jun 28 '19 at 17:07
  • 1
    As an aside, the previous entry in the change history is amusing: "*The RETURN VALUE section is updated to indicate that `strspn()` returns the length of `s`, and not `s` itself as was previously stated.*" 1. There is no `s` in the description of `strspn`, only `s1` and `s2`. 2. `strspn` doesn't return the length of either of its parameters. – melpomene Jun 28 '19 at 17:21
  • Good hunting to find the errata notice! – Jonathan Leffler Jun 28 '19 at 17:21
4

Yes, the computed length and the length of s1 will often differ, meaning the function must violate one of those descriptions.

But the first is obviously an error in the wording, as the latter must have been meant, so it doesn't matter.

There aren't many who could assert that strspn() was meant as a cumbersome cheap knockoff of strlen() with a straight face.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118