Re: C++0x static_assert(0, "") within a non-instantiated template
okay?
On Jun 23, 9:54 am, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:
static_assert(false, "Do not instantiate this template!!!");
IMO, a program should not be considered ill-formed, if this
static_assert declaration is placed within a template that is
not instantiated.
Mathias Gaunard wrote:
Of course it is not ill-formed.
I'm afraid that it *is* ill-formed, according to the current C++0x
Draft. (See below.)
No, the type-dependent BOOST_STATIC_ASSERT cannot be ill-formed before it is
instantiated. And a type-dependent template - as one would expect - may not
be instantiated until the template that it is dependent on - is
instantiated.
I think that kind of stuff is a lot used in boost, with their own
BOOST_STATIC_ASSERT emulation.
The documentation of BOOST_STATIC_ASSERT warns against doing
BOOST_STATIC_ASSERT(false). Instead it suggests doing
BOOST_STATIC_ASSERT(sizeof(T) == 0), within a template that should not
be instantiated.http://www.boost.org/doc/html/boost_staticassert.html
Correct. Using a type-dependent condition ensures that the
BOOST_STATIC_ASSERT is not evaluated immediately - in the context of its
enclosing template's definition.
But unfortunately both BOOST_STATIC_ASSERT calls appear to be
ill-formed, even within an uninstantiated template, as Gennaro Prota
explained to me (by e-mail). Quoting the current Draft, 14.6, Name
resolution [temp.res]:
"If no valid specialization can be generated for a template
definition, and that template is not instantiated, the template
definition is ill-formed, no diagnostic
required."http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2284.pdf
The compiler does generate a valid specialization in this situation -
because if the "SpecializeMePlease" template definition were ill-formed,
then no specialization would have been generated and the
BOOST_STATIC_ASSERT would never have been evaluated. In other words, in
order for BOOST_STATIC_ASSERT(sizeof(T)==0) to be ill-formed, the
"SpecializeMePlease" specialization that led to its instantiation - must be
valid.
And as Alberto Ganesh Barbati showed us that the expression sizeof(T)
never evaluates to zero (by definition), doing
BOOST_STATIC_ASSERT(sizeof(T) == 0) is ill-formed, just like
BOOST_STATIC_ASSERT(false).
The two static asserts are evaluated in different contexts - the latter,
being non-dependent is evaluated in the context of the template definition;
while the former, being type-dependent, is evaluated in the context of a
specialization.
So I guess the question is: is the Committee is willing to make an
exception for static_assert, and allow its first argument to be false,
within an uninstantiated template?
There is no exception needed. The language of the Standard is unambiguous:
the compiler must defer the resolution of a type-dependent expression until
the template has been specialized [?14.6/8]. But even without that rule, the
compiler has no alternative. Because even if the static assert evaluates to
false for every type T (which is not true, consider T=void which evaluates
to no value at all), the compiler still needs to identify the integer on the
left-hand side of the expression. After all, how could the compiler claim
that it had tested some number against zero for equality and yet not be able
specify exactly what that value (that did not compare equal to zero) was?
Greg
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]