
--- Yuval Ronen <ronen_yuval@yahoo.com> wrote:
Peter Dimov wrote:
If the interface takes unsigned char, passing 322 will result in the function receiving 66. This may generate a compiler warning, or it may not. Even if it does generate a warning, an explicit static_cast to unsigned char (because the programmer thinks that the value is in range) will silence it.
I don't get it. I won't surprise anyone if I'll say that the whole point of xxx_cast is to signal the programmer who writes this code that he's doing something fishy, and he should carefully check if this is ok. The best thing a library writer can do, is to provide the maximum compiler checks that will produce either an error or a warning in case of suspicious usage. Forcing the user to use a red-flagged cast is exactly such an example. If the user chose to supress the warning using a cast, then we could only assume he knows what he's doing.
Runtime checks are inferior because they A) hurt performance B) make code cumbersome so compile-time check are prefered.
Was there anything new and surprising in what I just said? I think not...
After reading this discussion I'm undecided about the best course of action :) Some thoughts, both for and against: - Does unsigned char always imply 0..255? Might there be a standards-conforming C++ implementation where char is not 8 bits? (Admittedly porting a sockets library, which inherently deals in sequences of octets, to this architecture could be rather difficult.) - If the motivation for this constructor is literal IP addresses, is the use case sufficiently common? Well known literals should be created some other way (e.g. by calling ipv4::address::loopback()). - Let's assume you are using it for literal IP addresses, and the constructor takes 4 ints and throws an exception when out of range. If you do not pass out of range values the optimiser can determine that the values are valid, so there would be no performance impact. - If the address was implemented as a C structure containing 4 unsigned chars it could be initialised using { 1, 2, 3, 4 }. This constructor, if it took unsigned chars, would be the equivalent of that. - Using unsigned chars doesn't just document the range of valid values, but also documents that an IP address is a 32-bit value composed of four 8-bit values. - If you want to use this constructor, you must know what you're doing, so be it on your own head ;) Cheers, Chris