Some More Small Additions to iostream

Doc. no.:N2580=08-0090
Date:2007-03-06
Author:James Kanze
email:james.kanze@gmail.com


Remove undefined behavior when inputing an integer

Motivation and scope

At present, it is impossible to input an integer without risk of undefined behavior, because the semantics in the C++ standard are defined in terms of scanf, and in the C standard, scanf says "If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined." This means that unless the program can determine in advance that the value will fit, it cannot be sure that undefined behavior will not occur. Given that the standard (including the C standard) already requires stdtol and stdtoul to detect overflow, therer doesn't seem to be any reason for not requiring it to be detected here. (Note that the text in the C standard also gives "does not have an appropriate type". I suspect that even in C, this is the prime motivation for the undefined behavior, and of course, in C++, this motivation is irrelevant, since our conversions are typesafe.)

Proposed text

In [facet.num.get.virtuals], paragraph 3, first point in Stage 3:

Add a manipulator to set basefield to 0

Motivation and scope

Currently, if the basefield in the format flags of an istream (actually in the base class of istream) is 0 (or fmtflags()), input of an integral types is "as if" a format specifier "%i" was used with scanf, in other words, as if 0 were passed as the base to stdtol or stdtoul, and as the C++ compiler reads its integral literals, with recognition of a leading "0" for octal, or a leading "0x" or "0X" for hexadecimal. Regretfully, there is no easy way for the user to set this: the value in this case doesn't have a name (e.g. like std::ios_base::dec, std::ios_base::hex or std::ios_base::oct), nor is there a manipulator to set it. The goal of this proposal is simply to give it a name (basefromuser, since I can't think of anything better), and provide a manipulator and a bit mask with the name, to make use easier and more intuitive.

Proposed text

In [ios.base], in the class definition, add:

    namespace std {
      class ios_base {
      public:
        class failure;

        typedef T1 fmtflags;
        static const fmtflags basefromuser;
        static const fmtflags boolalpha;
        static const fmtflags dec;
        //  ...
      };
    }
  

In [ios::fmtflags], in table 111, fmtflag effects:

Element Effect(s) if set
basefromuser converts integer input according to the rules which apply to literal constants in C++ [lex.icon]. (Note: for reasons of backward compatibility, this flag is required to have a numeric value of 0.)
boolalpha insert and extract bool bool type in alphabetic format
...

In [basefield.manip], add:

ios_base& basefromuser(ios_base& str);

Effects: Calls str.setf( ios_base::basefromuser, iso_base::basefield ).

Returns: str.

Add a manipulator to set floatfield to 0

Motivation and scope

Currently, if the floatfield in the format flags of an ostream (actually in the base class of ostream) is 0 (or fmtflags()), output of floating point values is "as if" a format specifier "%g" was used with printf; in other words, the style will be either fixed or scientific depending on the value converted. Regretfully, although this is the initial state, there is no easy way for the user to force this value if the initial state has been changed; the value in this case doesn't have a name (e.g. like std::ios_base::fixed or std::ios_base::scientific), nor is there a manipulator to set it. The goal of this proposal is simply to give it a name (adaptive, since I can't think of anything better), and provide a manipulator and a bit mask with the name, to make it easier to use and more intuitive.

Proposed text

In [ios.base], in the class definition, add:

    namespace std {
      class ios_base {
      public:
        class failure;

        typedef T1 fmtflags;
        static const fmtflags adaptive;
        static const fmtflags boolalpha;
        static const fmtflags dec;
        //  ...
      };
    }
  

In [ios::fmtflags], in table 111, fmtflag effects:

Element Effect(s) if set
adaptive Forces output conversion in the same way as is done by the "%g" or "%G" format of fprintf in C. (Note: for reasons of backward compatibility, this flag is required to have a numeric value of 0.)
boolalpha insert and extract bool bool type in alphabetic format
...

In [basefield.manip], add:

ios_base& adaptive(ios_base& str);

Effects: Calls str.setf( ios_base::adaptive, iso_base::floatfield ).

Returns: str.