From: Öö Tiib on
On May 25, 9:56 pm, Andy Venikov <swojchelo...(a)gmail.com> wrote:
> Andy Venikov wrote:
>
> <snip>
>
> Sorry to re-post my question, but I think the question got lost in
> between the lines.
>
> The following code compiles fine on both gcc 4.3 and Comeau online (with
> and without C++0x support) but produces different results. Gcc returns
> what I'd expect (true if T has foo and false if it doesn't) Comeau
> always returns false.
>
> I wonder, who's right?
>
> typedef unsigned int size_t;
>
> template <bool Test, typename T = void>
> struct enable_if;
>
> template <typename T>
> struct enable_if<true, T>
> {
> typedef T type;
> static const bool value = true;
>
> };
>
> template <typename T, typename Enable = void>
> struct has_foo
> {
> static const bool value = false;
>
> };
>
> template <typename T, typename Enable = void>
> struct take_address_of_foo
> {
> static const bool value = false;
>
> };
>
> template <typename T>
> struct take_address_of_foo<T,
> typename enable_if<0 < sizeof(&T::foo)>::type>
> {
> static const bool value = true;
>
> };
>
> template <typename T>
> struct has_foo<T, typename enable_if<take_address_of_foo<T>::value>::type>
> {
> static const bool value = true;
>
> };
>
> struct WithFoo
> {
> int foo(int, int, int);
>
> };
>
> struct NoFoo
> {
>
> };
>
> template <typename T, bool HasFoo = T::value>
> struct CompileError
> {
> typedef typename T::non_existing_type_brrr type;
>
> };
>
> //Force compile-error to show the results of has_foo<...>::type
> //Comeau alway returns false.
> //Gcc returns true for the "WithFoo" case
> typedef CompileError<WithFoo, has_foo<WithFoo>::value>::type T1;
> typedef CompileError<NoFoo, has_foo<NoFoo>::value>::type T2;
> typedef CompileError<int, has_foo<int>::value>::type T3;
>
> > Thanks,
> > Andy.


I think that it is undefined behavior in has_foo<WithFoo>::value.
[5.3.3] talks about every sort of types but fails to talk about
pointers to member functions and their overloads. Closest thing is:

[5.3.3/3] "The sizeof operator can be applied to a pointer to a
function, but shall not be applied directly to a function."

So Comeau probably thinks that pointers to member functions are
illegal for sizeof (always false) and gcc thinks that these are legal
(what you expect). Can not blame them because compiler has to do
something when situation is undefined.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Andy Venikov on
�� Tiib wrote:
<snip>


> I think that it is undefined behavior in has_foo<WithFoo>::value.
> [5.3.3] talks about every sort of types but fails to talk about
> pointers to member functions and their overloads. Closest thing is:
>
> [5.3.3/3] "The sizeof operator can be applied to a pointer to a
> function, but shall not be applied directly to a function."
>
> So Comeau probably thinks that pointers to member functions are
> illegal for sizeof (always false) and gcc thinks that these are legal
> (what you expect). Can not blame them because compiler has to do
> something when situation is undefined.

Hmm, interesting point.

Although typing this quick code in comeau:

struct A
{
void foo() {}
};

unsigned int n = sizeof(&A::foo);


compiled just fine...

(and by the way, the result of sizeof(&A::foo) is 8 -)

Thanks,
Andy.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]