
Boost : 
From: wb_at_[hidden]
Date: 20010914 17:23:19
Issue #1: special case

I have a concern about the way a special case of the gcd algorithm is
handled at the moment.
In common_factor.hpp we currently have:
// Nonrecursive case
template < unsigned long Value1 >
struct static_gcd_helper_t< Value1, 0UL >
{
BOOST_STATIC_CONSTANT( unsigned long, value = Value1 );
};
This is generally fine, but not when the template argument is also
0uL. In this case, the above code would give a result of 0uL  but
the Euclidean algorithm explicitly requires that not both its inputs be
zero. (The rationale, perhaps oversimplified, is that no divisor can
meaningfully be zero, since division by 0 is undefined, and no other
answer is correct.)
I respectfully recommend that a specialization, along the following
lines, be inserted to account for this special case and to force the
compiler to issue a diagnostic if user code ever happens to provoke
this situation:
// Euclidean algorithm excludes this case
template < >
struct static_gcd_helper_t< 0uL, 0uL >
{
// *** gcd<0,0>::value is explicitly not defined ***
};
Issue #2: extension

The classic Euclidean algorithm is not defined for negative values.
However, I believe it is a generally useful and straightforward
extension of the algorithm to provide a useful result in such a
circumstance. Indeed, the supplied runtime function already does so,
it seems; should not the compiletime computation do the same? (But
see Issue #3 below.)
Issue #3: question for experts

This code (as well, I'm sure, as many other programmers' code) uses the
C++ remainder operator % as if it were a mod operator. Technically, of
course, remaindering is a different operation from taking a modulus.
Does this distinction have any practical significance in the context of
the classical (nonnegative) Euclidean algorithm? (I believe not.)
But what about the case of the extension described above? Portability
is, of course, the true concern here: recall that the C++ Standard
describes (5.6/4) only the relationship between the division and
remainder operators, and does not prescribe either in isolation; only a
nonnormative footnote refers to a "preferred algorithm for integer
division ... in which the quotient is always rounded toward zero."
If use of remaindering on negative operands is deemed nonportable, then
I would recommend against the extension as described in Issue #2 above,
and also in the library's supplied runtime function, unless a portable
workaround can be provided.
 WEB
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk