Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added strerror_r examples.

...

If the noncompliant form of this test is truly faster, talk to your compiler vendor, because if these tests are equivalent, optimization should occur. If both forms have the same performance, prefer the portable form.

Anchor
ncce_strerror_r
ncce_strerror_r

Noncompliant Code Example (strerror_r)

The GNU libc implementation of strerror_r declares the function to return char*, in conflict with the POSIX ® specification. The following noncompliant code example relies on this return type to pass the return value as an argument to the %s formatting directive to fprintf. The behavior of the example will be undefined on a platform that declares the return type of strerror_r() to be int in accordance with POSIX.

Code Block
bgColor#FFCCCC

void f() {
  char buf[80];
  fprintf(stderr, "Error: %s\n",
          strerror_r(errno, buf, sizeof buf));
}

Anchor
cs_strerror_r
cs_strerror_r

Compliant Solution (strerror_r)

The compliant solution below disables the non-conforming declaration of strerror_r by explicitly requesting POSIX conformance before including the <string.h> header that declares the function and handles the function's failure by copying the "Unknown error" string into the buffer.

Code Block
bgColor#CCCCFF

#define _XOPEN_SOURCE 600
#include <string.h>

void f() {
  char buf[80];

  if (0 != strerror_r(errno, buf, sizeof buf))
    strcpy(buf, "Unknown error");

  fprintf(stderr, "Error: %s\n", buf);
}

The following alternate compliant solution avoids relying on the return type of strerror_r and takes care to set the first character of the buffer to NUL before calling the function to detect its success or failure and copies the "Unknown error" string into the buffer on failure.

Code Block
bgColor#CCCCFF

void f() {
  char buf[80];

  buf[0] = '\0';

  strerror_r(errno, buf, sizeof buf);
  if ('\0' == buf[0])
    strcpy(buf, "Unknown error");

  fprintf(stderr, "Error: %s\n", buf);
}

Risk Assessment

Unnecessary platform dependencies are, by definition, unnecessary. Avoiding these dependencies can eliminate porting errors resulting from invalidated assumptions.

...