Topic: C++0x static_assert(0, "") within a non-instantiated template okay?


Author: jam <farid.mehrabi@gmail.com>
Date: Tue, 3 Jul 2007 08:15:42 CST
Raw View
On Jul 3, 9:22 am, Greg Herlihy <gre...@pacbell.net> wrote:
> 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 until
> its template 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 until the template is
> instantiated.
>
> > 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
>
> A type-dependent name, such as the BOOST_STATIC_ASSERT(sizeof(T) == 0)
> may be evaluated only after a valid specialization has been generated
> from the template definition (otherwise the compiler would have
> already reported an error). So in a sense, the specialization must be
> valid before its instantiation of the BOOST_STATIC_ASSERT has an
> opportunity to be ill-formed.
>
> > 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 compiler must defer the resolution
> of a type-dependent expression in a template - until the context of
> the template's specialization. After all, even if the result of the
> evaluation is the same for every type T (which is not true in this
> case, consider T=void), the expression itself varies. So how could the
> compiler claim that the expression being asserted evaluated to false -
> yet not be able to identify what expression it was exactly that
> evaluated to false?
>
> Greg
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

If the goal is to prevent from specialization,could you not put the
template definition in a class/struct so that no body can specialize
it without modifying the nest or inheriting from that?(I know this is
ugly).

regards,
FM.

---
[ 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                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Tue, 3 Jul 2007 08:48:36 CST
Raw View
On 1 Jul., 16:22, AlbertoBarb...@libero.it (Alberto Ganesh Barbati)
wrote:
> No. The diagnostic is still required: the compiler should complain that
> the sizeof operator is applied to an invalid type ([expr.sizeof] para
> 1). So the program is ill-formed in both cases, but reason of
> ill-formedness is different: in order to provide the correct diagnostic
> the compiler must treat the expression as type-dependent.

OK, I see what you mean and your argument seem to the following:

Given any infeasible argument TFalse for T in the expression
sizeof(T)
has to be diagnosed ([expr.sizeof], "[..] The sizeof operator shall
not be
applied to an expression that has function or incomplete type,[..]).
This requirement contradicts the assertion of [temp.res]/7 "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."

Taking the position of devil's advocate I say, that [temp.res]/7
does not say anything about the reasons, why the specialization
could not be generated and this could also happen due to some
usually *diagnosable* reason. But in this special case the standard
allows that the failure need not be diagnosed.

Is this a valid position?

Greetings,

Daniel

---
[ 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                      ]





Author: Vladimir Marko <swelef@post.sk>
Date: Tue, 3 Jul 2007 10:14:13 CST
Raw View
On 3 Jul, 00:51, Greg Herlihy <gre...@pacbell.net> wrote:
> ... There is after all no requirement anywhere in the
> C++ Standard that states that a valid template specialization must
> also be well-formed. A "valid" specialization is simply one that the
> compiler can -generate- from the template definition without an error;
> there is no requirement that the compiler, when it subsequently
> -evaluates- the specialization, must find it to be well-formed.

Does the standard say what a "valid specialization" is?

If yes, please provide a reference. If not, then we should stop
discussing what the standard says and start discussing what
the standard _should_ say.

Regards,
Vladimir Marko

---
[ 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                      ]





Author: Vladimir Marko <swelef@post.sk>
Date: Wed, 4 Jul 2007 17:28:29 CST
Raw View
On 4 Jul, 04:52, gre...@pacbell.net (Greg Herlihy) wrote:
> On 7/3/07 6:14 AM, in article rLpii.54558$U01.543...@twister1.libero.it,
> "Alberto Ganesh Barbati" <AlbertoBarb...@libero.it> wrote:
> > ... So you are arguing that the requirement "if no *valid*
> > specialization can be generated" must not be read as "if no
> > *well-formed* specialization can be generated", correct?
>
> Exactly.
>
> > This makes a whole lot sense to me. However, if that interpretation is
> > correct, then we must reconsider the very beginning of this discussion,
> > because it would mean that the definition:
>
> >   template <typename T> void SpecializeMePlease(T) {
> >     static_assert(0, "Do not instantiate this template");
> >   }
>
> > is indeed well-formed! Personally I'd like that, because it makes thing
> > soo much simple.
>
> No, the SpecializeMePlease template definition is ill-formed in your example
> because the expression used in the static_assert test, is non-dependent
> (whereas any expression containing a sizeof(T) is always value-dependent,
> see    14.6.2.3). And a non-dependent expression is evaluated in the context
> of the template definition. Since the static_assert (obviously) fails, the
> template definition itself is ill-formed (...).

You seem to assume that non-dependent expressions _are_
evaluated even without instantiating any specialization. That may
be what some compilers do, but the _only_ paragraph in the
standard that could allow them to do so (14.6/7 AFAIK) doesn't
apply because we _assumed_ that a template definition is not
ill-formed even if all instantiations are.

Can you, please, forget about what _compilers_ do and focus
on what the standard says? And if there are different
interpretations, when you assume one can you stick to it?

Regards,
Vladimir


---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Tue, 24 Jul 2007 21:32:31 GMT
Raw View
When we were discussing whether a compiler would be allowed to reject
static_assert(sizeof(T)==0, "") within a uninstantiated template, a
concept related question remained unanswered...

Alberto Ganesh Barbati wrote on Sunday, 1 July 2007:
>
> Niels Dekker - no return address ha scritto:
>> BTW, I guess that by definition sizeof(T) > 0 is true for every
>> *DefaultConstructible* type T.  So a C++0x compiler would be *allowed*
>> to diagnose the following template definition, even without being
>> instantiated:
>>
>>   #include <concepts>  // For the std::DefaultConstructible concept.
>>
>>   template<std::DefaultConstructible T>
>>   void TemplateFunc(void) {
>>     static_assert(sizeof(T)==0, "Ill-formed!");
>>   }
>>
>> I would rather have the C++0x Standard stating explicitly that a static
>> assert declaration has no effect within an uninstantiated template.
>
> Hmm... I haven't fully grasped all the details of concepts, so I may be
> wrong, but can't you declare a type to be DefaultConstructible before
> providing a definition for such type?

Indeed, you can't.  :-)  As Douglas Gregor just explained, at the
ConceptGCC mailing list:
>
> DefaultConstructible [...] cannot be satisfied by an incomplete
> class, because one needs to complete the class to see if it has a
> default constructor.
>
( http://www.osl.iu.edu/MailArchives/conceptgcc/2007/07/0126.php )


Kind regards, Niels

---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Tue, 12 Jun 2007 21:39:57 GMT
Raw View
Would it be allowed to do a static_assert with zero as first argument,
within a template?  I would like to do so, to prevent instantiation of
the template!  So will the following be a valid C++0x program?

  ////////////////////////////////////////////////////////////
  template <typename T> void SpecializeMePlease(T) {
    static_assert(0, "Do not instantiate this template");
  }

  template <> void SpecializeMePlease<int>(int) {
  }

  int main() {
    SpecializeMePlease(1);
  }
  ////////////////////////////////////////////////////////////

Kind regards,
--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center

---
[ 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                      ]





Author: Vladimir Marko <swelef@post.sk>
Date: Fri, 29 Jun 2007 09:26:51 CST
Raw View
On 29 Jun, 07:35, Greg Herlihy <gre...@pacbell.net> wrote:
> On Jun 23, 9:54 am, nore...@this.is.invalid (Niels Dekker - no return
>
> address) wrote:
> > >> static_assert(false, "Do not instantiate this template!!!");

[The previous articles were slightly inconsistent in their quotes
and responses. The main subject of discussion moved to
    static_assert(sizeof(T)==0,"Do not instantiate this template");
in a template definition where T is a template parameter.
BOOST_STATIC_ASSERT is being used as a replacement of
static_assert.]

> > 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.

Let's be clear about this. BOOST_STATIC_ASSERT is not ill-formed
before
it's instantiated. The _template definition_ is ill-formed, because no
valid
specialization can be generated. You would need a _very_ sophisticated
compiler to diagnose that, but it is nevertheless ill-formed.

> > 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.

With all respect, this is nonsense. The compiler does not generate
a valid specialization, because none exists. The template definition
is ill-formed even without ever being instantiated (the quote provided
is very clear about it). And, finally, the compiler often needs to
instantiate a template specialization to find out _if_ it's ill-
formed,
making your last sentence rather ridiculous.

While the compilers are likely to accept the code, the _language_
says the template definition is ill-formed. There is a workaround,
though:

template <typename>
struct always_false { static const bool value = false; };

template <typename T>
class specialize_me
{
    static_assert(always_false<T>::value,"don't instantiate this
template");
};

Here, we could provide a specialization of always_false to make
it possible to generate a valid instantiation of specialize_me, thus
the definition of specialize_me can't be deemed ill-formed.

Regards,
Vladimir Marko

---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Sat, 30 Jun 2007 14:46:07 GMT
Raw View
  [ Thanks Greg, for revitalizing the discussion ]

Alberto Ganesh Barbati wrote:
> So it's not true that sizeof(T) > 0 for *every* type. It's true only
> for *complete* types (those that can be instantiated to object).

I hope you still agree that there is *no* type T, for which
(sizeof(T)==0) evaluates to true...

> The compiler cannot "optimize" the expression sizeof(T) == 0 assuming that
> it always evaluates to false, because it might be ill-formed for some T
> (for example: void). This is enough to force the compiler to treat the
> expression as type-dependent.

Interesting.  Do you mean to say that if a program is ill-formed because
of a static_assert(sizeof(T)==0, "") within an uninstantiated template,
the compiler would not be allowed to say so?  If so, the program would
be "ill-formed, no diagnostic /allowed/" !!!

BTW, I guess that by definition sizeof(T) > 0 is true for every
*DefaultConstructible* type T.  So a C++0x compiler would be *allowed*
to diagnose the following template definition, even without being
instantiated:

  #include <concepts>  // For the std::DefaultConstructible concept.

  template<std::DefaultConstructible T>
  void TemplateFunc(void) {
    static_assert(sizeof(T)==0, "Ill-formed!");
  }

I would rather have the C++0x Standard stating explicitly that a static
assert declaration has no effect within an uninstantiated template.


Vladimir Marko wrote [about passing (sizeof(T)==0) to a static assert,
within an uninstantiated template]:
> While the compilers are likely to accept the code, the _language_
> says the template definition is ill-formed. There is a workaround,
> though:
>
> template <typename>
> struct always_false { static const bool value = false; };
>
> template <typename T>
> class specialize_me
> {
>     static_assert(always_false<T>::value,"don't instantiate this template");
> };
>
> Here, we could provide a specialization of always_false to make
> it possible to generate a valid instantiation of specialize_me, thus
> the definition of specialize_me can't be deemed ill-formed.

Thanks for your support!  :-)  I do like your always_false struct, as I
find the use of always_false<T>::value as static_assert-argument more
clear and less "tricky" than the use of (sizeof(T)==0).  I actually
wrote a very simular struct myself:

  template <typename> struct type_dependent_false {
    enum { value = false }; };

( Using an enum instead of a static const, as recommended by
Nicolai Josuttis and David Vandevoorde, C++ Templates: Metaprograms,
17.2 Enumeration Values versus Static Constants.
http:://www.awprofessional.com/articles/article.asp?p=30667&seqNum=2 )

Unlike the sizeof(T)==0 trick, this approach can be extended to non-type
template arguments and template template arguments:

  template<int> struct int_dependent_false {
    enum { value = false }; };

  template<const void*> struct ptr_dependent_false {
    enum { value = false }; };

  template<template<class> class> struct template_dependent_false {
    enum { value = false }; };

Unfortunately the list could go on and on, for each possible kind of
template template argument:

  template<template<class, class> class>
  struct template_dependent_false2 {
    enum { value = false }; };

  template<template<class, class, class> class>
  struct template_dependent_false3 {
    enum { value = false }; };

Is there a more "generic" technique to implement an "always false
struct" for each kind of template argument?  Gennaro Prota and I
recently had an e-mail discussion on this approach as well, but we
couldn't think of an alternative...

Kind regards,

  Niels

---
[ 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                      ]





Author: =?iso-8859-1?q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Sun, 1 Jul 2007 09:23:09 CST
Raw View
On 29 Jun., 17:26, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
> So, it's not true that sizeof(T) > 0 for *every* type. It's true only for
> *complete* types (those that can be instantiated to object). The
> compiler cannot "optimize" the expression sizeof(T) == 0 assuming that
> it always evaluates to false, because it might be ill-formed for some T
> (for example: void). This is enough to force the compiler to treat the
> expression as type-dependent.

I'm not convinced. What I see, if I interpret 14.6/7 strictly, that a
cute
compiler could recognize that it can distinguish two cases:

1) sizeof(T) is wellformed (because the type is complete): Here always
results: sizeof(T) > 0. So the assertion must always be wrong and for
no complete type can the template be spezialized.

2) sizeof(T) is *not* wellformed for any incomplete type, thus for no
incomplete type can the template be spezialized.

So, the compiler can (theoretically) proof, that only one of these
cases
is possible and that in neither of them a valid specialization could
be
generated. So the template definition is ill-formed in all cases and
the
"no-diagnostic"-situation of 14.6/7 applies.

Is such an interpretation valid?

Greetings from Bremen,

Daniel Kr   gler


---
[ 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                      ]





Author: Greg Herlihy <greghe@pacbell.net>
Date: Mon, 2 Jul 2007 17:51:28 CST
Raw View
On 7/1/07 8:23 AM, in article
1183291569.419981.61530@c77g2000hse.googlegroups.com, "Daniel Kr   gler"
<daniel.kruegler@googlemail.com> wrote:

> On 29 Jun., 17:26, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
> wrote:
>> So, it's not true that sizeof(T) > 0 for *every* type. It's true only for
>> *complete* types (those that can be instantiated to object). The
>> compiler cannot "optimize" the expression sizeof(T) == 0 assuming that
>> it always evaluates to false, because it might be ill-formed for some T
>> (for example: void). This is enough to force the compiler to treat the
>> expression as type-dependent.
>
> I'm not convinced. What I see, if I interpret 14.6/7 strictly, that a
> cute
> compiler could recognize that it can distinguish two cases:
>
> 1) sizeof(T) is wellformed (because the type is complete): Here always
> results: sizeof(T) > 0. So the assertion must always be wrong and for
> no complete type can the template be spezialized.

The entire purpose of the static_assert( sizeof(T) == 0) is to ensure
that
any specialization of the template will be ill-formed - but to do so
in such
a way (specifically: with a value-dependent expression) that the
template
definition itself remains well-formed. Because as long as the template
definition is well-formed (meaning the compiler is able to look up all
non-dependent names in the template definition), then the compiler
will be
able to generate a valid (though not necessarily, well-formed)
template
specialization from it. And that is exactly what happens here, the
compiler
is able to generate a specialize_me specialization for any type T.
Now, the
specialization turns out to be ill-formed (for one reason or another),
but
the ill-formedness of the specialization has no bearing on the
well-formedness of the template definition that generated it.

> 2) sizeof(T) is *not* wellformed for any incomplete type, thus for no
> incomplete type can the template be spezialized.

On the contrary - there is no type T for which a specialization cannot
be
generated in this example. There is after all no requirement anywhere
in the
C++ Standard that states that a valid template specialization must
also be
well-formed. A "valid" specialization is simply one that the compiler
can
-generate- from the template definition without an error; there is no
requirement that the compiler, when it subsequently -evaluates- the
specialization, must find it to be well-formed.

> So, the compiler can (theoretically) proof, that only one of these
> cases
> is possible and that in neither of them a valid specialization could
> be
> generated. So the template definition is ill-formed in all cases and
> the
> "no-diagnostic"-situation of 14.6/7 applies.
>
> Is such an interpretation valid?

No. The mistake here is equating an "invalid" specialization with one
that
is ill-formed. In reality, the two describe distinct stages in the
processing of a template specialization, one applies to its generation
and
the other to its subsequent evaluation.

After all, the very first time that a compiler parses a template
definition
it can easily tell whether the definition is well-formed or not (and
if the
definition is ill-formed, a diagnostic is required at that point.)
Otherwise, the compiler generates a valid specialization for the
provided
template type parameters. This specialization is then evaluated in the
context of its point of instantiation.

This distinction between the generation and the evaluation of a
template
specialization can be demonstrated simply by instantiating a value-
dependent
static_assert or a value-dependent BOOST_STATIC_ASSERT (which,
somewhat
ironically, relies on taking the sizeof an incomplete type to render
the
program ill-formed when the asserted expression is not true) and
noting the
error that the compiler reports. Now, if the compiler reports that the
template specialization (and not the template definition) is ill-
formed,
then it must be the case that the compiler was able to generate a
valid
specialization from the template definition - otherwise a failure to
do so
would have required a diagnostic at the point.

Or to put it another way: a template definition is not ill-formed even
if
every specialization of that template is ill-formed. In fact, it
proves just
the opposite: that an ill-formed template specialization must have a
well-formed template definition - because an ill-formed template
definition
would have been unable to generate any template specialization - and a
specialization that was never generated - cannot be ill-formed.

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                      ]





Author: Greg Herlihy <greghe@pacbell.net>
Date: Mon, 2 Jul 2007 23:22:00 CST
Raw View
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 until
its template 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 until the template is
instantiated.

> 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

A type-dependent name, such as the BOOST_STATIC_ASSERT(sizeof(T) == 0)
may be evaluated only after a valid specialization has been generated
from the template definition (otherwise the compiler would have
already reported an error). So in a sense, the specialization must be
valid before its instantiation of the BOOST_STATIC_ASSERT has an
opportunity to be ill-formed.

> 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 compiler must defer the resolution
of a type-dependent expression in a template - until the context of
the template's specialization. After all, even if the result of the
evaluation is the same for every type T (which is not true in this
case, consider T=void), the expression itself varies. So how could the
compiler claim that the expression being asserted evaluated to false -
yet not be able to identify what expression it was exactly that
evaluated to false?

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                      ]





Author: =?iso-8859-1?q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Wed, 13 Jun 2007 10:47:05 CST
Raw View
On Jun 12, 6:39 pm, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:
> Would it be allowed to do a static_assert with zero as first argument,
> within a template?  I would like to do so, to prevent instantiation of
> the template!  So will the following be a valid C++0x program?

Comeau Online with C++0x extensions refuses this code with:

"ComeauTest.c", line 2: error: static assertion failed with
          "Do not instantiate this template"
      static_assert(0, "Do not instantiate this template");

You need to make the first expression dependant on the template
argument somehow for this trick to work.

--
 Pedro Lamar   o


---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Tue, 19 Jun 2007 21:57:24 GMT
Raw View
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D MODERATOR'S COMMENT:=20

Please refer to the FAQ for what to do if a post does not appear after a=20
day or so.


=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D END OF MODERATOR'S COMMENT
>> Would it be allowed to do a static_assert with zero as first argument,
>> within a template?  I would like to do so, to prevent instantiation of
>> the template!

Pedro Lamar=E3o replied:
> Comeau Online with C++0x extensions refuses this code with:
> "ComeauTest.c", line 2: error: static assertion failed with
>           "Do not instantiate this template"
>       static_assert(0, "Do not instantiate this template");
>=20
> You need to make the first expression dependant on the template
> argument somehow for this trick to work.

Thanks!  So is an expression like (sizeof(T) =3D=3D 0) dependant on T?=20
Comeau appears to accept the following program:

  ////////////////////////////////////////////////////////////
  template <typename T> void SpecializeMePlease(T) {
    static_assert( (sizeof(T) =3D=3D 0),
      "Do not instantiate this template");
  }

  template <> void SpecializeMePlease<int>(int) {
  }

  int main() {
    SpecializeMePlease(1);
  }
  ////////////////////////////////////////////////////////////

Would a compiler be allowed to reject the program, because it "knows"
that (sizeof(T) =3D=3D 0) is always false?

[Note: 5 days ago, I posted a slightly different follow-up to
comp.std.c++, but it never appeared on the newsgroup so far...]

--=20
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
Scientific programmer at LKEB, Leiden University Medical Center

---
[ 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                      ]





Author: jam <farid.mehrabi@gmail.com>
Date: Wed, 20 Jun 2007 10:12:46 CST
Raw View
On Jun 13, 1:39 am, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:
> Would it be allowed to do a static_assert with zero as first argument,
> within a template?  I would like to do so, to prevent instantiation of
> the template!  So will the following be a valid C++0x program?
>
>   ////////////////////////////////////////////////////////////
>   template <typename T> void SpecializeMePlease(T) {
>     static_assert(0, "Do not instantiate this template");
>   }
>
>   template <> void SpecializeMePlease<int>(int) {
>   }
>
>   int main() {
>     SpecializeMePlease(1);
>   }
>   ////////////////////////////////////////////////////////////
>
> Kind regards,
> --
> Niels Dekkerhttp://www.xs4all.nl/~nd/dekkerware
> Scientific programmer at LKEB, Leiden University Medical Center
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

sorry I just posted some garbage.silly me.damn

---
[ 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                      ]





Author: jam <farid.mehrabi@gmail.com>
Date: Wed, 20 Jun 2007 11:16:46 CST
Raw View
On Jun 13, 1:39 am, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:
> Would it be allowed to do a static_assert with zero as first argument,
> within a template?  I would like to do so, to prevent instantiation of
> the template!  So will the following be a valid C++0x program?
>
>   ////////////////////////////////////////////////////////////
>   template <typename T> void SpecializeMePlease(T) {
>     static_assert(0, "Do not instantiate this template");
>   }
>
>   template <> void SpecializeMePlease<int>(int) {
>   }
>
>   int main() {
>     SpecializeMePlease(1);
>   }
>   ////////////////////////////////////////////////////////////
>
> Kind regards,
> --
> Niels Dekkerhttp://www.xs4all.nl/~nd/dekkerware
> Scientific programmer at LKEB, Leiden University Medical Center
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

I think that assert is evaluated at run time and it does not prevent
compilation.Do you  want to suggest a compile time assertion mechanism
as a new feature in C++???

regards,
FM.

---
[ 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                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Wed, 20 Jun 2007 17:39:34 CST
Raw View
On Jun 20, 7:16 pm, jam <farid.mehr...@gmail.com> wrote:

> I think that assert is evaluated at run time and it does not prevent
> compilation.Do you  want to suggest a compile time assertion mechanism
> as a new feature in C++???

static_assert is a new C++0x feature that is a compile-time assert.


---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Thu, 21 Jun 2007 16:11:38 GMT
Raw View
Mathias Gaunard wrote:
> static_assert is a new C++0x feature that is a compile-time assert.

It's even a keyword, in C++0x!  The lastest Draft (N2284) says in
chapter 7 [dcl.dcl]:
  "In a static_assert-declaration the constant-expression shall be an
integral constant expression (5.19). If the value of the
expression when converted to bool is true, the declaration has no
effect. Otherwise, the program is ill-formed, and
the resulting diagnostic message (1.4) shall include the text of the
string-literal, except that characters not in the basic
source character set (2.2) are not required to appear in the diagnostic
message."=20
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2284.pdf

Now it's quite common to explicitly pass false to a runtime assert:
  assert(false);  // Do not execute this line of code!!!

I would like to be able to do something similar, using static_assert:
  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.

Pedro Lamar=E3o already remarked that the first argument of static_assert
needs to be dependant on the template argument somehow.  So is it
appropriate to pass (sizeof(T) =3D=3D 0) as argument to static_assert?=20

I find the use of (sizeof(T) =3D=3D 0) rather unelegant.  But more
importantly:
1. I wonder, does the outcome of (sizeof(T) =3D=3D 0) really _depend_ on =
the
template argument T?
2. This approach does not work for non-type template arguments.

What do you think?

Kind regrards,

  Niels

---
[ 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                      ]





Author: =?iso-8859-1?q?Pedro_Lamar=E3o?= <pedro.lamarao@gmail.com>
Date: Thu, 21 Jun 2007 11:11:59 CST
Raw View
On Jun 19, 6:57 pm, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:

>   ////////////////////////////////////////////////////////////
>   template <typename T> void SpecializeMePlease(T) {
>     static_assert( (sizeof(T) == 0),
>       "Do not instantiate this template");
>   }

> Would a compiler be allowed to reject the program, because it "knows"
> that (sizeof(T) == 0) is always false?

A quick search in the current draft: neither [basic.types] nor
[expr.sizeof] state explicitly that every sizeof() expression will
result > 0.

--
 Pedro Lamar   o


---
[ 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                      ]





Author: Mathias Gaunard <loufoque@gmail.com>
Date: Fri, 22 Jun 2007 09:57:03 CST
Raw View
On 21 juin, 18:11, nore...@this.is.invalid (Niels Dekker - no return
address) wrote:

> I would like to be able to do something similar, using static_assert:
>   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.

Of course it is not ill-formed.
You do not need to use T in the static assert.

I think that kind of stuff is a lot used in boost, with their own
BOOST_STATIC_ASSERT emulation.

---
[ 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                      ]





Author: jam <farid.mehrabi@gmail.com>
Date: Sat, 23 Jun 2007 11:53:13 CST
Raw View
On Jun 21, 3:39 am, Mathias Gaunard <loufo...@gmail.com> wrote:
> On Jun 20, 7:16 pm, jam <farid.mehr...@gmail.com> wrote:
>
> > I think that assert is evaluated at run time and it does not prevent
> > compilation.Do you  want to suggest a compile time assertion mechanism
> > as a new feature in C++???
>
> static_assert is a new C++0x feature that is a compile-time assert.
>
> ---
> [ comp.std.c++ is moderated.  To submit articles, try just posting with ]
> [ your news-reader.  If that fails, use mailto:std-...@ncar.ucar.edu    ]
> [              --- Please see the FAQ before posting. ---               ]
> [ FAQ:http://www.comeaucomputing.com/csc/faq.html                     ]

thaks but this post was a stupid mistake that I discovered  it just
after sending.Now I would like to ask you about more details .
Would it not be better if a mechanism was introduced to write some
code which is executed at compile time instead of just asserting
statically?
regards,
FM

---
[ 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                      ]





Author: noreply@this.is.invalid (Niels Dekker - no return address)
Date: Sat, 23 Jun 2007 16:54:56 GMT
Raw View
>> 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.)

> 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

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

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).

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?

Kind regards,

  Niels

---
[ 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                      ]