Boost logo

Boost :

From: Boris Gubenko (Boris.Gubenko_at_[hidden])
Date: 2007-11-05 14:33:39


Test error_code_test[_dll] fails on HP-UX and AIX and I'd expect it to
fail on Tru64 also (Tru64 results are currently not on the web).

The test checks message for error code -1 in both system and posix category
and expects it to be "Unknown error". For system category:

  ec = error_code( -1, system_category );
  std::cout << "error_code message for -1 is \"" << ec.message() << "\"\n";
  BOOST_CHECK( ec.message().substr( 0, 13) == "Unknown error" );

IIUC, the assumption is that strerror(invalid-error-code) either returns
a pointer to a string starting with "Unknown error", which is the case on
Linux -- see below, or returns a null pointer in which case
libs/system/src/error_code.cpp maps it to "Unknown error" string:

      const char * c_str = std::strerror( ev );
      return std::string( c_str ? c_str : "Unknown error" );

The problem with this assumption is that there is no requirement in the C
standard that the message string generated by strerror() for an invalid
error code starts with "Unknown error" -- see excerpt from C99 below. For
example, on HP-UX, strerror() returns an empty string and on Tru64 it
returns "Error -1 occurred."

As for the null pointer, strerror() cannot return it -- again, see excerpt
from C99 below. X/Open explicitly states that strerror() may signal error
by setting errno, but not by returning any particular value:

  "
  Upon successful completion, strerror() returns a pointer to the
  generated message string. On error errno may be set, but no return
  value is reserved to indicate an error.
  "

It does not mean that error_code.cpp should not check for a null pointer
as a precaution against non-conformant implementation of strerror().

In libs/system/test/error_code_test.cpp, the check for the message
string corresponding to error code -1 should either be conditionalized
for different platforms or removed. Here is conditionalization for
system category for HP-UX and Tru64 (I don't have IBM machine at my
disposal and cannot figure out conditionalization for AIX):

#if defined(__hpux)
  BOOST_CHECK( *(ec.message().c_str()) == 0 );
#elif defined(__osf__)
  BOOST_CHECK( ec.message().c_str() == "Error -1 occurred." );
#else
   BOOST_CHECK( ec.message().substr( 0, 13) == "Unknown error" );
#endif

x.c

---
#include <stdio.h>
#include <string.h>
int main() {
  const char * c_str = strerror( -1 );
  printf( "%s\n", c_str ? c_str : "Unknown error" );
}
bash-3.00$ uname
Linux
bash-3.00$ cc x.c && a.out
Unknown error 18446744073709551615
bash-3.00$
bash-2.03$ uname
HP-UX
bash-2.03$ cc x.c && a.out
bash-2.03$
cosf.zko.hp.com> uname
OSF1
cosf.zko.hp.com> cc x.c && a.out
Error -1 occurred.
cosf.zko.hp.com>
>From C99:
---------
       7.21.6.2  The strerror function
       Synopsis
       [#1]
               #include <string.h>
               char *strerror(int errnum);
       Description
       [#2] The strerror function maps the number in  errnum  to  a
       message  string.  Typically, the values for errnum come from
       errno, but strerror shall map any value of  type  int  to  a
       message.
       [#3]  The  implementation  shall  behave  as  if  no library
       function calls the strerror function.
       Returns
       [#4] The strerror function returns a pointer to the  string,
       the  contents  of  which  are  locale-specific.   The  array
       pointed to shall not be modified by the program, but may  be
       overwritten by a subsequent call to the strerror function.
Thanks,
  Boris

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk