Boost logo

Boost :

From: Christopher Kohlhoff (chris_at_[hidden])
Date: 2006-01-12 08:21:37


--- Yuval Ronen <ronen_yuval_at_[hidden]> 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


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