Document number: N3758
Programming Language C++, Library Subgroup
 
Emil Dotchevski, emil@revergestudios.com
 
2013-08-30

Standard exception information types for std::exception

I. Overview

This proposal defines standard exception information types compatible with N3757.

II. Motivation

Defining standard exception information types improves compatibility between programs and libraries that throw and/or handle exceptions.

III. Impact

Defining standard exception information types as proposed supplements N3757 and does not affect any other parts of the standard library.

IV. Proposed Text

In the standard header <exception> add the following type definitions in namespace std (refer to N3757 for the definition of set<>):

Type Description
struct errinfo_throw_function
{
  typedef char const * type;
};

struct errinfo_throw_file
{
  typedef char const * type;
};

struct errinfo_throw_line
{
  typedef int type;
};

These types specify the name of the function, the source file name and line number containing the throw statement that emitted the exception, as if __PRETTY_FUNCTION__, __FILE__ and __LINE__ are passed separately to std::exception::set<> at the point of the throw. Implementations are encouraged, but not required, to include this information automatically in all exceptions of types that derive from std::exception.

struct errinfo_api_function
{
  typedef char const * type;
};

Used when throwing exceptions in case a call to a no-throw API function fails, to indicate the name of that function. For example:

fread(ptr,size,count,f);
if( ferror(f) )
{
  file_error e; //derives from std::exception
  e.set<errinfo_api_function>("fread");
  throw e;
}
                
struct errinfo_file_name
{
  typedef std::string type;
};

Specifies a relevant file name for exceptions used to report file errors, using UTF-8 encoding. Example:

try
{
  FILE * f=fopen("name","rb");
  if( !f )
    throw file_open_error(); //derives from std::exception
  .....
}
catch( std::exception & e )
{
  e.set<errinfo_file_name>("name");
  throw;
}
struct errinfo_fileno
{
  typedef int type;
};

struct errinfo_file
{
  typedef FILE * type;
};

These types can be used to specify a relevant file descriptor or FILE pointer in exceptions used to report file errors. One possible use case is in contexts that operate on more than one file, to determine the correct file name to pass to set<errinfo_file_name> depending on the file information reported by a lower level function.

struct errinfo_errno
{
  typedef errno_code type;
};

where errno_code is defined as:

struct errno_code
{
  int value;
  errno_code(int value):
    value(value)
  {
  }
};

Specifies a relevant errno code (note the implicit conversion from int.) The errno_code type is a wrapper needed to convert the errno code to string for the purposes of std::exception::diagnostic_information (see N3757), for example by the following accessible operator<< overload (or equivalent):

ostream & operator<<( ostream & _S, errno_code const & _X )
{
  return _S << _X.value << '(' << strerror(_X.value) << ')';
}

V. Implementability

A proof of concept implementation for N3757 is available in Boost. See boost/exception/N3757.hpp and libs/exception/test/N3757_test.cpp in http://svn.boost.org/svn/boost/trunk.