Topic: template instantiation does not obey short-circuit semantics of &&


Author: notbob@tessellation.com (Robert Allan Schwartz)
Date: Wed, 7 May 2003 23:52:37 +0000 (UTC)
Raw View
The program:

template <typename T>
class is_class
{
public:
 static const bool value = false;
};

template <typename T>
class is_empty_helper_class_1 : public T
{
 int unused[256];
};

template <typename T>
class is_empty_helper_class_2
{
 int unused[256];
};

template <typename T>
class is_empty
{
public:
 static const bool value =
  (
   is_class<T>::value
  &&
   (
    sizeof(is_empty_helper_class_1<T>)
   ==
    sizeof(is_empty_helper_class_2<T>)
   )
  );
};

#include <iostream>

int main()
{
 std::cout << "is_class<bool>::value = " << is_class<bool>::value <<
std::endl;
 std::cout << "is_empty<bool>::value = " << is_empty<bool>::value <<
std::endl;

 return 0;
}

results in compilation errors for both g++ v3.2 and metrowerks v7.0,
claiming bool cannot be a base class (for is_empty_helper_class_1).
The compilers appear to be evaluating the second operand to the &&
even though the first operand evaluates to false.

I believe the compilers should not evaluate the second operands in
this case.

What does the standard say?

Thanks,

Robert Schwartz

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: derekledbetter@mindspring.com (Derek Ledbetter)
Date: Thu, 8 May 2003 03:27:11 +0000 (UTC)
Raw View
On Wed, 7 May 2003 16:52:37 -0700, Robert Allan Schwartz wrote
(in message <1166fd92.0305071548.62d6758d@posting.google.com>):

>I believe the compilers should not evaluate the second operands in
>this case.
>
>What does the standard say?

You're right that the second operand of logical AND is not evaluated if
the first operand is false.  But the standard doesn't say that the
second operand doesn't have to be a valid expression.

--
Derek Ledbetter
derekledbetter@attbi.com
"Life's short and hard like a body-building elf."

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]





Author: amelie.francois@free.fr (Francois Dumont)
Date: Thu, 8 May 2003 18:56:48 +0000 (UTC)
Raw View
> I believe the compilers should not evaluate the second operands in
> this case.
>
> What does the standard say?
>

Hello

  I am sorry for you but it is well known that metaprogrammation do
not work as classic programmation. The compiler is going to evaluate
all your conditions even if one of those is a constant false value.
You have to use an intermediate class to perform what you are looking
for:

template <typename T, bool isClass>
struct is_empty_aux
{
 static const bool value = false;
};

template <typename T>
struct is_empty_aux<T, true>
{
  static const bool value =
    (
     sizeof(is_empty_helper_class_1<T>)
    ==
     sizeof(is_empty_helper_class_2<T>)
    );
};

template <typename T>
struct is_empty
{
 static const bool value = is_empty_aux<T, is_class<T>::value>::value;
};

  This way, in all case, the is_empty_aux<T, true> specialization will
be syntaxically checked but it will be semantically checked only if
is_class<T>::value is true avoiding the compile error when it is
false.

Best Regards

---
[ 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.jamesd.demon.co.uk/csc/faq.html                       ]