This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
- From: "daniel.kruegler at googlemail dot com" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: Mon, 13 Feb 2012 09:18:40 +0000
- Subject: [Bug c++/52224] [C++0x] Generic operator gets pulled into compile-time expression
- Auto-submitted: auto-generated
- References: <bug-52224-4@http.gcc.gnu.org/bugzilla/>
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52224
Daniel KrÃgler <daniel.kruegler at googlemail dot com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |daniel.kruegler at
| |googlemail dot com
--- Comment #1 from Daniel KrÃgler <daniel.kruegler at googlemail dot com> 2012-02-13 09:18:40 UTC ---
I can confirm that for gcc 4.7.0 20120211 (experimental) as well. To ease
comparison with other compiler I rewrote it into fully C++03 compatible form,
also removing all library dependencies:
//---
template<bool, class>
struct enable_if {};
template<class T>
struct enable_if<true, T> { typedef T type; };
template <class T> struct my_class {};
template <typename T> struct is_mine { enum { value = false }; };
template <typename T> struct is_mine<my_class<T> > { enum { value = true }; };
template <typename E1, typename E2>
struct either_is_mine
{ static const bool value = is_mine<E1>::value || is_mine<E2>::value; };
template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
operator||(E1 e1, E2 e2);
template <typename E1, typename E2>
typename enable_if<either_is_mine<E1, E2>::value, int>::type
test(E1 e1, E2 e2);
int main()
{
test(3, 12);
}
//---
Comeau online processes it nicely, rejecting the code as expected. clang online
(3.0) runs into a similar endless loop, which becomes an immediate segmentation
fault, if the unnamed enums in the is_mine template are changed to named ones.
I removed both the exception specification and the inline specifier from the
operator|| overload, because they do not change the result.
The enums in the is_mine template lead to an infinite recursion, because of the
alternate dependency to operator|| overload. The first argument is
int,
the second argument is the enum type
decltype(is_mine<int>::value),
the third is the enum type
decltype(is_mine<decltype(is_mine<int>::value)>::value),
etc. I'm unsure whether this is a design problem or a compiler problem, but
there is an easy workaround for this: Just replace the enums used within both
is_mine templates by static const bool. This prevents that endless recursion,
because there is no infinite type change going on.