Re: Query regd. "Modern C++ Design" program.
* frame:
I am trying to compile the following program, whose fragments are
presented in Section 2.1: "Compile-Time Assertions" of Chapter 2:
"Techniques" of "Modern C++ Design" by Andrei Alexandrescu, but
couldn't;
//////////////////////////////////////////////////////////////////////
template<bool> struct CompileTimeChecker
{
CompileTimeChecker(...);
};
template<> struct CompileTimeChecker<false> { };
#define STATIC_CHECK(expr, msg) \
{\
class ERROR_##msg {}; \
(void)sizeof(CompileTimeChecker<(expr) != 0>((ERROR_##msg())));\
}
template <class To, class From>
To safe_reinterpret_cast(From from)
{
STATIC_CHECK(sizeof(From) <= sizeof(To),
Destination_Type_Too_Narrow);
return reinterpret_cast<To>(from);
}
int main(int argc, char* argv[]){
void* aptr = 0;
char c = safe_reinterpret_cast<char>(aptr);
return 0;
}
//////////////////////////////////////////////////////////////////////
As per the book, an expected result should be a compile-time error
occurence due to the "STATIC_CHECK" macro. But this hasn't been the
case with a couple of compilers (gcc, Comeau), I tried to compile this
program. I find both compiler's normal "reinterpret_cast" performing
the functionality of "safe_reinterpret_cast".
Well, at least MSVC 7.1's reinterpret_cast unsafely converts the void*
pointer to char, not even a warning (but of course many silly-warnings
about much else that's clearly not anything to worry about, as usual).
Apart from these, I am
also getting an error "invalid application of `sizeof' to a function
type" for the statement "(void)sizeof(CompileTimeChecker<(expr) !=
0>((ERROR_##msg())));".
Can somebody please clarify whether anything is amiss with the above
program?
Anything that can be construed as a function declaration is one.
I'm not sure whether that formally applies to the above, especially
since as I recall the technique of using extra parentheses to force
something to be interpreted as an expression is an example in the
standard for fixing just this case, but one does not need to know about
the standard's formalities in order to apply a (better) cure. One such
cure is to name the ERROR_##msg instance, e.g. x, and another cure is to
provide and use an ERROR_##msg constructor with e.g. int argument
instead of the default constructor. A cure that's slightly different is
of course to use some other compile time assert, such as Boost's (which
corresponds to Andrei's original one, as is so often the case in Boost;
perhaps the whole Boost library should have been renamed as "The library
of applications of Andrei Alexandrescu's techniques" (sort of like "The
artist formerly known as Prince", but in reverse); but anyway, I like
the original compile time assert much better than the one above).
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]