Boost logo

Boost :

From: Darin Adler (darin_at_[hidden])
Date: 1999-11-05 08:17:34


We should change the Boost implementation of implicit_cast to a simple
implementation that does not attempt to disable any warnings.

The current implementation goes to some length to disable implicit
conversion warnings. Under Visual C++, "#pragma warning(disable:4244)" is
used to disable the warnings on implicit numeric conversions. Under
Metrowerks CodeWarrior, an unsuccessful attempt is made to use "#pragma
warn_implicitconv off". No attempt is made to disable the corresponding
warning in gcc, presumably because there's no way to do it.

Review the purpose of the implicit numeric conversion warning. Loosely put,
the warning is intended to catch cases where a numeric type is implicitly
converted to a "smaller" type. For example, a double implicitly converted to
a float is potentially dangerous and triggers the warning.

Here's an example of some code that runs into a problem that might be solved
by implicit_cast:

    #include <algorithm>
    #include <iostream>

    int main()
    {
        float x = 2;
        int y = 3;
        std::cout << std::max(x, y) << '\n';
        return 0;
    }

The call to std::max doesn't compile because x and y do not have the same
type. A possible fix is to use implicit_cast:

    #include <algorithm>
    #include <boost/cast.hpp>
    #include <iostream>
    using boost::cast::implicit_cast;

    int main()
    {
        float x = 2;
        int y = 3;
        std::cout << std::max(x, implicit_cast<float>(y)) << '\n';
        return 0;
    }

The goal here is simply to get the effect of an implicit type conversion
without introducing an additional local variable. The advantage of
implicit_cast over other alternative casts is that someone reading the code
can immediately tell that this is simply an implicit conversion, not a
potentially dangerous cast.

Note that in a real example, the types of the expression might not be so
clear. In the case of a template, for example, the type might not even be
named in the same source file as the call to implicit_cast.

If the type of one of the variable y changes, the code converts a double to
a float, the kind of possibly-dangerous conversion that the implicit numeric
conversion warning is intended to catch:

    #include <algorithm>
    #include <boost/cast.hpp>
    #include <iostream>
    using boost::cast::implicit_cast;

    int main()
    {
        float x = 2;
        double y = 3;
        std::cout << std::max(x, implicit_cast<float>(y)) << '\n';
        return 0;
    }

In this case, I expect the implicit numeric conversion warning from the
compiler. I am converting a double to a float. If I want to do the
conversion explicitly and get rid of the warning, there are many other casts
to choose from. The best for this case is probably numeric_cast:

    #include <algorithm>
    #include <boost/cast.hpp>
    #include <iostream>
    using boost::cast::numeric_cast;

    int main()
    {
        float x = 2;
        double y = 3;
        std::cout << std::max(x, numeric_cast<float>(y)) << '\n';
        return 0;
    }

The point of implicit_cast is to have a cast that only allows conversions
that could have been done in other contexts where implicit conversion takes
place: parameter passing or variable initialization, for example. Just
because the implicit conversion is explicitly invoked doesn't justify
turning off implicit numeric conversion warnings.

A cast that can do only implicit conversions, but disables implicit numeric
conversion warnings, is not as useful as a cast that can do only implicit
conversions with all the same warnings that you get in any other context
where an implicit conversion is done.

    -- Darin


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