Boost logo

Boost :

From: Gennaro Prota (gennaro_prota_at_[hidden])
Date: 2006-06-25 18:15:56


On Sun, 25 Jun 2006 15:25:45 -0400, Beman Dawes <bdawes_at_[hidden]>
wrote:

>Gennaro Prota wrote:
>> On Sun, 25 Jun 2006 10:00:42 -0400, Beman Dawes <bdawes_at_[hidden]>
>> wrote:
>>
>>> [...] In
>>> particular, class error_code to encapsulate error codes from the
>>> operating system and class system_error to be thrown by exceptions.
>>>
>>> See
>>> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1975.html#Diagnostics-library
>>
>> I've just looked at this paper, but not at the code (I'm working
>> contemporarily on three things now, so better I don't add a fourth
>> :)).

Well, for today I've finished with dynamic_bitset so I'm having a
second look at this :)

>> Here are my "off the top of my head" remarks:
>>
>> * something I've remembered of when seeing the names "system_error",
>> "error_code": why not "file_system"? (maybe this was already discussed
>> in the filesystem library review, but I don't recall)

I'm still curious about that (since filesystem was introduced in
boost, actually).

>>
>> * the name system_error_type is a bit misleading to me, as it seems to
>> refer to the type of system_error (i.e. system_error :)) not to the
>> type used by the OS API. Maybe it could be renamed to
>>
>> native_system_error_type
>>
>> or something like that?
>
>I was also quite unhappy with the names in the proposal to the
>committee. Thus the version in the Boost vault has what I hope are
>improved names, less likely to cause confusion.

Well, sysno_t is IMHO better than system_error_type because it a)
doesn't cause any fallacious mental association with system_error and
because b) it's consistent with errno_t.

That said, the wording at the url you provide still perplexes me:

    Type system_error_type [now sysno_t] is the implementation-defined
    type used by the operating system to report error codes.

It seems to me (please correct me if I'm wrong) that this refers to
the type actually used by the operating system, not to an integer type
providing a mapping to numbers. Well, it could even by in turn a
mapping but I don't see why casting in stone that it must be an
integer. Though I don't know of any system which doesn't use numbers
for that, I still think other types are perfectly reasonable.

You know very well that if I return 0 from main, or call exit(0) it's
the implementation responsibility to translate 0 to the
implementation-defined form to indicate successful completion. Plan
9's exit() actually returns a string :) Then a POSIX compatibility
environment (APE) is available that implements exit(int) -i.e.
provides the mapping required by the C standard. This is just an
example to show that _under the hood_ of the C implementation things
can actually be different and require a mapping. Does the sentence
above want what is under the hood or what the C or C++ implementation
exposes?

My preferred name, FWIW, is still native_system_error[_type].

>
>If Boosters like the new names, I'll propose them to the committee. The
>intent is synchronize both versions so they use the same names.
>
>So please looks at the new names and see if you think they are an
>improvement.
>
>> * please, don't "hardcode" the usage of std::string and std::wstring;
>
>When dealing directly with the operating system, it is hard to see how
>to avoid that. Please be a bit more specific, and suggest alternatives.

I didn't mean hardcoding character literals and such (not that I've
noticed that in your code). I meant not using
basic_string/string/wstring at all, because that creates unnecessary
coupling with the string library and is a less flexible and generic<>
approach than iostreams. I've thought a lot about this, and the more
time elapses the more I get convinced. Let's consider, for instance,
the case of std::bitset<>. What if I want my bitset represented as

  ttftt [t=true, f=false]

instead of

  11011

And why not

  xx0xx

? Of course to_string() cannot do that, unless one wants to add a
pletora of extra parameters. The stream approach instead is locale
aware and allows any kind of special formatting. And it is highly
customizable. As soon as I can, I'll provide a little helper class to
aid in customizing input and output of dynamic_bitset as indicated
above. My example about ipv4 should make the point even clearer: in
general there's no unique way to represent an object as a sequence of
characters, and what we actually want when doing conversion to string
is *formatting*. A sequence of characters is just a special form of
textual representation.

BTW, once inserters and extractors work correctly you can use
lexical_cast<> for simple, raw, text conversion needs.

With the iostream approach you have a clear separation between a) the
class which contains the data b) the textual representation of those
data c) a generic name, operator <<, or operator >> to connect them
and convert to and from character representations.

>
>> I'm noticing this is happening everywhere in the standard, including
>> TR1, TR2 and one of the library issues about std::bitset<>; as James
>> Kanze made me notice, there's no conceptual reason why strings and
>> std::bitsets (or system_error, of fstreams) should know about each
>> other: if one wants the "textual representation" of an object the
>> idiom to use is operator<<, which is also a standard "name" suitable
>> for generic programming; obtaining the textual representation is a
>> matter of formatting and there's no reason why one should have e.g.
>> to_string() rather than to_ber_encoding() or to_xml(). Not to speak of
>> the fact that a conversion to string may require a locale object,
>> which you automatically get if using a stream.
>>
>> Just to make an example: supposing one want to implement
>> ipv4::to_string(), what should be done with octets whose value is less
>> than 100 or less than 10?
>>
>> a) 192.168.0.10
>> b) 192.168.0.010
>> c) 192.168.000.010
>> ....
>>
>> As you see, this is formatting.
>>
>> This is a Java design error that C++ should not repeat (think also of
>> Java's hashCode() -that's not different from to_string(), actually; a
>> class shouldn't know about strings more than it knows about hash
>> codes)
>
>That is beyond the scope of anything I can deal with here. You need to
>write a paper for the committee, identifying specific places in the
>standard (or TR1/TR2) where you think that is happening, and where
>possible suggest solutions to the problems you identify.

Would a DR be suitable? I was specifically alluding, for instance to
lib DR 434:

<http://google.com/group/comp.std.c++/browse_thread/thread/188ddd204ebd67da/739035f50ae29ab8?#739035f50ae29ab8>

and to

<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1475.html#15>

>>
>> * "The class error_code defines the type of objects used to
>> identify specific errors originating from the operating
>> system."
>>
>> Who says this is a numeric code? It could be a handle, for instance,
>> or any kind of opaque object. Why not calling the class "error_id"?
>
>The native operating system's sysno_t is implementation defined. I'll
>take a look, but it should be possible for it to be something other than
>a numeric type.
>
>> * many constructors are not explicit; is that intentional?
>
>I'm not sure which constructors you are looking at. The only converting
>constructor I see is already explicit.

I was again looking at the paper, not at your code. I'm sure you
istinctively used explicit where it made sense.

--Gennaro.


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