
On Sun, 25 Jun 2006 15:25:45 -0400, Beman Dawes <bdawes@acm.org> wrote:
Gennaro Prota wrote:
On Sun, 25 Jun 2006 10:00:42 -0400, Beman Dawes <bdawes@acm.org> 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#Diagnosti...
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.