Boost logo

Boost Users :

From: Dave Dribin (dave-ml_at_[hidden])
Date: 2006-07-20 14:41:53


On Jul 20, 2006, at 10:34 AM, me22 wrote:
> I'm not a fan of that macro hackery, however...

Neither am I. :) I do feel a bit dirty for doing that, and wouldn't
recommend it, if you can avoid it. But it's a system header than I
cannot change. I will probably end up copying it to my project,
renaming it to avoid a conflict, and do a search/replace, actually.

> The problem is that the classes can't properly act "like ints". The
> way they are now they can't be used in a union, as you've mentions.

I totally agree that they should act as much like ints as possible.

> But take out the constructors and then the following rather logical
> program doesn't work any more:
> #include <boost/integer/endian.hpp>
> #include <iostream>
>
> int main() {
> boost::integer::big4_t x = 42;
> std::cout << x << "\n";
> }

True, but a workaround is to do it in two steps:

        boost::integer::big4_t x;
        x = 42;

> And it can no longer be initialised in member initializer lists. I
> don't know whether this or unions is a more pressing concern, however.

At least initialization has a workaround by doing it in two steps.
There is no work around to allow them in unions.

One argument for favoring unions over initialization is that a prime
requirement of the endian types are they "must be suitable for I/O -
in other words, must be memcpyable." Hence, they are designed to be
used in structs and and then used directly with I/O, i.e. it's great
for file formats. I doubt HFS+ is alone in using unions for file
formats. I can see other uses cases for unions, too. It would be a
shame if it were not possible to model these.

> Do SFINAE-awayed constructors prevent a class from being used in
> unions? That might be a way to allow both if an eventual review can't
> come to a conclusion.

"SFINAE-awayed constructors" is a new term for me. After a bit of
Google work, I'm still not sure I understand SFINAE enough to know
what it can do, and if could help here. But as far as I know, *any*
constructor prevents a class from being used in a union.

One possible solution is to use add static init() methods to the
template:

   static endian init(T i) { endian e; e = i; return e; }

Then, you could initialize it like:

   boost::integer::big4_t x = boost::integer::big4_t::init(43);

Not perfect, but less ugly then using two steps, especially, if you
ignore the namespaces:

   big_t x = big_t::init(43);

-Dave


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net