Comeau and G++ disagree. Compiler bug?



 DEVELOP > c-Plus-Plus > Comeau and G++ disagree. Compiler bug?

LINK TO THIS PAGE  


rating :  0   |  0


  Page 1 of 1

1

 
Topic: DEVELOP > c-Plus-Plus
User: "Alan Woodland"
Date: 12 Aug 2007 03:45:36 PM
Object: Comeau and G++ disagree. Compiler bug?
Hi,
I was trying to come up with obscure C++ questions in the style of GoTW
and ran across this unexpected difference between G++ and comeau. Can
anyone point me in the direction of the correct result for this program?
#include <iostream>
namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}
template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }
void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }
int main() {
f(A::Foo());
return 0;
}
G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Whereas Comeau allows it (I only tried it online, so I don't for certain
know what f(A::Foo()); actually resolved to. Comeau version was:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ noC++0x_extensions
Thanks,
Alan
.

User: "Victor Bazarov"

Title: Re: Comeau and G++ disagree. Compiler bug? 12 Aug 2007 04:06:22 PM
Alan Woodland wrote:

I was trying to come up with obscure C++ questions in the style of
GoTW and ran across this unexpected difference between G++ and
comeau. Can anyone point me in the direction of the correct result
for this program?


#include <iostream>

namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}

template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }

void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }

int main() {
f(A::Foo());
return 0;
}

G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

Whereas Comeau allows it (I only tried it online, so I don't for
certain know what f(A::Foo()); actually resolved to. Comeau version
was:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ noC++0x_extensions

AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By the
time ADL is employed, the syntax 'f(A::Foo())' cannot be "explicit type
conversion (functional notation)". It only can be "type conversion" if
'f' is already deduced as a type, which it cannot be since 'A::f' type
is not visible.
That aside, it cannot be 'f(A::Foo&)' since the reference to a non-const
'A::Foo' cannot be bound to a temporary ('A::Foo()'), which leaves the
only choice: the template. Now, if you change the "plain ref" function
to
void f(A::Foo const&);
then it will be chosen over the template since in rules of the overload
resolution a non-template function is always preferred over a template
instantiation.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
.
User: "James Kanze"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 02:31:58 AM
On Aug 12, 11:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:

Alan Woodland wrote:

I was trying to come up with obscure C++ questions in the style of
GoTW and ran across this unexpected difference between G++ and
comeau. Can anyone point me in the direction of the correct result
for this program?
#include <iostream>
namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}
template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }
void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }
int main() {
f(A::Foo());
return 0;
}
G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Whereas Comeau allows it (I only tried it online, so I don't for
certain know what f(A::Foo()); actually resolved to. Comeau version
was:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ noC++0x_extensions

AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By the
time ADL is employed, the syntax 'f(A::Foo())' cannot be "explicit type
conversion (functional notation)". It only can be "type conversion" if
'f' is already deduced as a type, which it cannot be since 'A::f' type
is not visible.

That may have been the intent---in fact, it probably was, since
the current draft has been changed to state explicitly that ADL
will ignore any names that aren't names of functions. But I'm
not sure that it's that clear in the currently official version
of the standard; it's one of those things which can be
interpreted in different ways. If I interpret the error message
from g++ correctly, it's saying that ADL was applied because
the expression was a function call, and then the results of
function overload resolution meant that it wasn't a function;
the official standard isn't too clear about what to do in this
case, so they treated it as an error.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
User: "Victor Bazarov"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 07:04:30 AM
James Kanze wrote:

On Aug 12, 11:06 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:

Alan Woodland wrote:

I was trying to come up with obscure C++ questions in the style of
GoTW and ran across this unexpected difference between G++ and
comeau. Can anyone point me in the direction of the correct result
for this program?


#include <iostream>


namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}


template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }


void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }


int main() {
f(A::Foo());
return 0;
}


G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.


Whereas Comeau allows it (I only tried it online, so I don't for
certain know what f(A::Foo()); actually resolved to. Comeau version
was:
Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for
ONLINE_EVALUATION_BETA1 Copyright 1988-2007 Comeau Computing. All
rights reserved. MODE:strict errors C++ noC++0x_extensions


AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By
the time ADL is employed, the syntax 'f(A::Foo())' cannot be
"explicit type conversion (functional notation)". It only can be
"type conversion" if 'f' is already deduced as a type, which it
cannot be since 'A::f' type is not visible.


That may have been the intent---in fact, it probably was, since
the current draft has been changed to state explicitly that ADL
will ignore any names that aren't names of functions. But I'm
not sure that it's that clear in the currently official version
of the standard; it's one of those things which can be
interpreted in different ways. If I interpret the error message
from g++ correctly, it's saying that ADL was applied because
the expression was a function call, and then the results of
function overload resolution meant that it wasn't a function;
the official standard isn't too clear about what to do in this
case, so they treated it as an error.

According to the new draft, if 'f' were an object with an overloaded
function call operator:
namespace A {
class Foo { };
struct ff {
public:
void operator()(const Foo&)
{ std::cout << "operator()" << std::endl; }
} f;
}
void f(const A::Foo&) { std::cout << "regular func" << std::endl; }
int main() {
f(A::Foo());
return 0;
}
, it wouldn't have been found either, but I am not sure about the
current wording (or GNU folks' interpretation of it). I don't have
G++ to try this one, but VC++ and Comeau online accept it.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
.
User: "Alan Woodland"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 07:36:27 AM

AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By
the time ADL is employed, the syntax 'f(A::Foo())' cannot be
"explicit type conversion (functional notation)". It only can be
"type conversion" if 'f' is already deduced as a type, which it
cannot be since 'A::f' type is not visible.

That may have been the intent---in fact, it probably was, since
the current draft has been changed to state explicitly that ADL
will ignore any names that aren't names of functions. But I'm
not sure that it's that clear in the currently official version
of the standard; it's one of those things which can be
interpreted in different ways. If I interpret the error message
from g++ correctly, it's saying that ADL was applied because
the expression was a function call, and then the results of
function overload resolution meant that it wasn't a function;
the official standard isn't too clear about what to do in this
case, so they treated it as an error.


According to the new draft, if 'f' were an object with an overloaded
function call operator:

namespace A {
class Foo { };
struct ff {
public:
void operator()(const Foo&)
{ std::cout << "operator()" << std::endl; }
} f;
}

void f(const A::Foo&) { std::cout << "regular func" << std::endl; }

int main() {
f(A::Foo());
return 0;
}

, it wouldn't have been found either, but I am not sure about the
current wording (or GNU folks' interpretation of it). I don't have
G++ to try this one, but VC++ and Comeau online accept it.

Looks like this one doesn't work either:
g++-4.1 -Wall -std=c++98 /tmp/test.cc
/tmp/test.cc: In function 'int main()':
/tmp/test.cc:9: error: 'A::f' is not a function,
/tmp/test.cc:12: error: conflict with 'void f(const A::Foo&)'
/tmp/test.cc:15: error: in call to 'f'
Alan
.

User: "James Kanze"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 08:25:35 AM
On Aug 13, 2:04 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:
[...]

According to the new draft, if 'f' were an object with an overloaded
function call operator:
namespace A {
class Foo { };
struct ff {
public:
void operator()(const Foo&)
{ std::cout << "operator()" << std::endl; }
} f;
}
void f(const A::Foo&) { std::cout << "regular func" << std::endl; }
int main() {
f(A::Foo());
return 0;
}
, it wouldn't have been found either, but I am not sure about the
current wording (or GNU folks' interpretation of it). I don't have
G++ to try this one, but VC++ and Comeau online accept it.

That's a good point. I think that in the current standard, that
is clearly legal. The fact that the draft makes it illegal
could break some code, and possibly wasn't intended. Maybe
someone should raise the point in comp.std.c++. (I'm leaving on
vacation very shortly, and will be off line for close to three
weeks, or I'd do it myself.)
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
User: "Victor Bazarov"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 09:43:25 AM
James Kanze wrote:

On Aug 13, 2:04 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:

[...]

According to the new draft, if 'f' were an object with an overloaded
function call operator:


namespace A {
class Foo { };
struct ff {
public:
void operator()(const Foo&)
{ std::cout << "operator()" << std::endl; }
} f;
}


void f(const A::Foo&) { std::cout << "regular func" << std::endl; }


int main() {
f(A::Foo());
return 0;
}


, it wouldn't have been found either, but I am not sure about the
current wording (or GNU folks' interpretation of it). I don't have
G++ to try this one, but VC++ and Comeau online accept it.


That's a good point. I think that in the current standard, that
is clearly legal. The fact that the draft makes it illegal
could break some code, and possibly wasn't intended. Maybe
someone should raise the point in comp.std.c++. (I'm leaving on
vacation very shortly, and will be off line for close to three
weeks, or I'd do it myself.)

I don't believe it's so bad. Let's examine the "issue". If the
code was broken before the new Standard (the error was reported),
how would suddenly making the code working *break* anything? Are
you thinking of some SFINAE technique here?
If I remove the '::f' function from the code above, VC++ and Comeau
(the ones I can test now) do not find 'f', not sure what G++ would
do. Let's say that G++ would accept it (is that a bug?), relying
on their understanding of ADL. The new standard would then prohibit
finding 'f' since it's not a function. Fixing it should not really
be such a PITA (provided G++ folks do implement the new Standard
correctly after it's adopted), and they could still provide their
old behaviour as another extension <g>.
I'll post the question in comp.std.c++.
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
.




User: "Alan Woodland"

Title: Re: Comeau and G++ disagree. Compiler bug? 12 Aug 2007 04:37:00 PM
Victor Bazarov wrote:

Alan Woodland wrote:

#include <iostream>

namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}

template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }

void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }

int main() {
f(A::Foo());
return 0;
}

G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.


AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By the
time ADL is employed, the syntax 'f(A::Foo())' cannot be "explicit type
conversion (functional notation)". It only can be "type conversion" if
'f' is already deduced as a type, which it cannot be since 'A::f' type
is not visible.

That aside, it cannot be 'f(A::Foo&)' since the reference to a non-const
'A::Foo' cannot be bound to a temporary ('A::Foo()'), which leaves the
only choice: the template. Now, if you change the "plain ref" function
to

void f(A::Foo const&);

then it will be chosen over the template since in rules of the overload
resolution a non-template function is always preferred over a template
instantiation.

Thanks,
The non-const reference and temporary was deliberately designed to catch
someone out after a previous question where it had been const and the
version of f in namespace A had been a function to illustrate Koenig
lookup. I wasn't 100% sure it would pick the function over the
constructor for f though.
Am I right in thinking non-const temporary reference binding will be
changing in C++0X? Or am I getting confused? I seem to recall reading
something about it a while back.
I'll be filing a bug against g++ shortly given that g++ (GCC) 4.3.0
20070720 also seems to have this problem.
Alan
.
User: "Victor Bazarov"

Title: Re: Comeau and G++ disagree. Compiler bug? 12 Aug 2007 04:57:10 PM
Alan Woodland wrote:

Victor Bazarov wrote:

Alan Woodland wrote:

#include <iostream>

namespace A {
class Foo { };
struct f {
public:
f(const Foo& f) { std::cout << "ctor" << std::endl; }
};
}

template <typename T>
void f(const T& t) { std::cout << "Template ref" << std::endl; }

void f(A::Foo& f) { std::cout << "Plain ref" << std::endl; }

int main() {
f(A::Foo());
return 0;
}

G++ doesn't accept it and says:
test.cc: In function 'int main()':
test.cc:5: error: 'struct A::f' is not a function,
test.cc:14: error: conflict with 'void f(A::Foo&)'
test.cc:17: error: in call to 'f'
G++ version was:
g++ (GCC) 4.1.3 20070718 (prerelease) (Debian 4.1.2-14)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There
is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.


AFAICT, G++ is mistaken. It cannot be a construction of a temporary
of type 'f', types are not found using ADL for this syntax. In order
to look 'f' up using ADL, it has to be deemed a function call. By
the time ADL is employed, the syntax 'f(A::Foo())' cannot be
"explicit type conversion (functional notation)". It only can be
"type conversion" if 'f' is already deduced as a type, which it
cannot be since 'A::f' type is not visible.

That aside, it cannot be 'f(A::Foo&)' since the reference to a
non-const 'A::Foo' cannot be bound to a temporary ('A::Foo()'),
which leaves the only choice: the template. Now, if you change the
"plain ref" function to

void f(A::Foo const&);

then it will be chosen over the template since in rules of the
overload resolution a non-template function is always preferred over
a template instantiation.

Thanks,

The non-const reference and temporary was deliberately designed to
catch someone out after a previous question where it had been const
and the version of f in namespace A had been a function to illustrate
Koenig lookup. I wasn't 100% sure it would pick the function over the
constructor for f though.

Am I right in thinking non-const temporary reference binding will be
changing in C++0X? Or am I getting confused? I seem to recall reading
something about it a while back.

Not that I know of. There is a new concept being introduced, an rvalue
reference (declaration syntax '&&'). But you can't initialise a regular
reference to non-const object with a temporary, still.

I'll be filing a bug against g++ shortly given that g++ (GCC) 4.3.0
20070720 also seems to have this problem.

I would wait a couple of days... I have a sneaky feeling James Kanze
will want to chime in. <g>
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
.
User: "James Kanze"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 02:36:27 AM
On Aug 12, 11:57 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:

Alan Woodland wrote:

I'll be filing a bug against g++ shortly given that g++ (GCC) 4.3.0
20070720 also seems to have this problem.

I would wait a couple of days... I have a sneaky feeling James Kanze
will want to chime in. <g>

Obviously:-). In this case, I don't find the standard as clear
as you do (but your interpretation is definitly one possible
one, and probably the intended one), so I wouldn't treat g++ too
harshly; they may just have interpreted the standard
differently. The current draft, however, adds an additional
qualification to ADL which says, literally "All names except
those of (possibly overloaded) functions and function templates
are ignored." So I'm sure that whatever the original reasons
why g++ behaves as it does, they'll want to change it to conform
to what the future standard will say.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34
.
User: "bnonaj"

Title: Re: Comeau and G++ disagree. Compiler bug? 13 Aug 2007 03:44:00 AM
James Kanze wrote:

On Aug 12, 11:57 pm, "Victor Bazarov" <v.Abaza...@comAcast.net> wrote:

Alan Woodland wrote:

I'll be filing a bug against g++ shortly given that g++ (GCC) 4.3.0
20070720 also seems to have this problem.


I would wait a couple of days... I have a sneaky feeling James Kanze
will want to chime in. <g>


Obviously:-). In this case, I don't find the standard as clear
as you do (but your interpretation is definitly one possible
one, and probably the intended one), so I wouldn't treat g++ too
harshly; they may just have interpreted the standard
differently. The current draft, however, adds an additional
qualification to ADL which says, literally "All names except
those of (possibly overloaded) functions and function templates
are ignored." So I'm sure that whatever the original reasons
why g++ behaves as it does, they'll want to change it to conform
to what the future standard will say.

--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

I think we're all grateful for both Victor and James. They both make a
lot of valuable contributions to this newsgroup. As for the G++ compiler
flagging an error, that is what I would have expected, and I'm indebted
to Victor and James for pointing out the lack of clarity in the current
C++ standard on this point. Keep up the good work, I certainly
appreciate it and hopefully it improves my C++ knowledge reading the
feedback given on this newsgroup.
JB
.






  Page 1 of 1

1

 


Related Articles
 

NEWER

pg.1232     pg.940     pg.716     pg.544     pg.412     pg.311     pg.234     pg.175     pg.130     pg.96     pg.70     pg.50     pg.35     pg.24     pg.16     pg.10     pg.6     pg.3     pg.1

OLDER