-
Key: VSIPL16-18
-
Legacy Issue Number: 18216
-
Status: open
-
Source: dpdx.net ( Brooks Moses)
-
Summary:
This issue is copied from an internally-filed issue at Mentor that dates
back to the early days of the specification. Since that time, some
usage patterns have emerged that appear useful – most notably, the
implicit use of a length_type when a Domain<1> is required. This
particular case should either be preserved or additional overloads of
the relevant functions should be added.However, in general this complaint is still quite relevant – for
instance, we should not be implicitly converting a length_type value to
a LU_solver object.Note that I have not edited this to account for any changes to the
specification (either section numbers or normative changes) since the
issue was initially submitted in 2005.In most cases, the resolution – adding an "explicit" keyword to many of
these constructors – seems straightforward and obvious. Chances are
very high that any existing code which is broken thereby was erroneous
in the first place.
Many of the constructors specified can take a single argument but are
not declared "explicit". A complete list:Domain<1>(length_type)
Index<1>(index_type)
Dense<D>(Domain<D> const&)
const_Vector(Block&)
const_Vector(Vector const&)- const_Vector<>(Vector const&)
Vector<>(Block&)
template <typename T0, typename Block0>
Vector(Vector<T0, Block0> const&)
const_Matrix<>(Block&) - const_Matrix<>(Matrix const&)
Matrix(Block&)
template <typename T0, typename Block0>
Matrix(Matrix<T0, Block0> const&)
const_Tensor<>(Block&) - const_Tensor<>(Tensor const&)
Tensor(Block&)
template <typename T0, typename Block0>
Tensor(Tensor<T0, Block0> const&)
lud<>(length_type) or LU_solver<>(length_type), see #29
Rand<>(index_type)
Of these, only the starred conversions are defensible, and even
they will require some design adjustments. All the
rest are a problem; most are fixable simply by adding "explicit".
For the case of Domain<1>, this will require redesign of other
components to restore convenient usage; perhaps similarly for some
of the conversions from Block&.Also, in the requirements list 6.3, the line View(Block &) should be
annotated to indicate that the conversion should not be implicit.To expand on why these implicit conversions are dangerous...
First, implicit conversions from native numeric types are especially
problematic because of the promiscuous conversions among those types,
inherited from C, that occur even before calling the constructor.
As a result, any numeric type, whether int, float, char, or bool,
matches the constructor argument, and thus is accepted freely in
place of the class type by any function that takes an argument of
that type, regardless of whether it makes sense. These mistakes
can be very hard to spot; sometimes it results from calling f(a,b)
when f(b,a) was meant. (Functions declared to take numeric types
can sometimes be made safer by overloading with another that takes
a different, but acceptable, numeric type.)Second, implicit conversions of any kind provoke annoying compiler
error messages complaining of ambiguities when more than one
conversion path is possible. The more implicit conversions that
are possible, the more frequently such ambiguities occur. The
workaround for such an ambiguity is to add a cast to the exact
type, but casts are themselves a source of errors, and besides
obscuring the logic of the code, they eliminate the convenience
the implicit conversion was supposed to provide.Third, in cases where one conversion path is favored by the compiler
over another, the compiler may silently choose what the programmer
would consider the wrong one.Fourth, template argument matching ignores conversions, making those
that do work less conveniently useful than they may seem. - const_Vector<>(Vector const&)
-
Reported: VSIPL++ 1.2 — Tue, 23 Oct 2012 04:00 GMT
-
Updated: Fri, 6 Mar 2015 20:57 GMT
VSIPL16 — Dangerous implicit conversions
- Key: VSIPL16-18
- OMG Task Force: Vector Image Signal Processing Specifications 1.6 RTF