public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* C++ conversion rules ???
@ 1999-06-19  7:35 Marc Espie
  1999-06-19 16:01 ` Martin v. Loewis
  1999-06-30 15:43 ` Marc Espie
  0 siblings, 2 replies; 8+ messages in thread
From: Marc Espie @ 1999-06-19  7:35 UTC (permalink / raw)
  To: egcs, egcs-bugs

I have trouble understanding why the following fragment:

struct A {
	operator const char *() const { return "";}
	operator char *() { return "";}
};

A a;
const char *b = a;


will yield

a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
a.C:9: warning:   for conversion from `A' to `const char *'
a.C:9: warning:   because conversion sequence for the argument is better

even after reading the ANSI C++ drafts I have...

Note that, if I remove one const,  e.g.,
	operator const char *() { return "";}
the code no longer warns...

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-19  7:35 C++ conversion rules ??? Marc Espie
@ 1999-06-19 16:01 ` Martin v. Loewis
  1999-06-20  5:08   ` Charles Galambos
  1999-06-30 15:43   ` Martin v. Loewis
  1999-06-30 15:43 ` Marc Espie
  1 sibling, 2 replies; 8+ messages in thread
From: Martin v. Loewis @ 1999-06-19 16:01 UTC (permalink / raw)
  To: espie; +Cc: egcs, egcs-bugs

> I have trouble understanding why the following fragment:

I'm not sure what your question is; I'll try to answer it
anyway. However, comp.std.c++ is a better place for this kind of
problem.

> a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
> a.C:9: warning:   for conversion from `A' to `const char *'
> a.C:9: warning:   because conversion sequence for the argument is better

The compiler is right in calling A::operator char *(). 

This is a case for overload resolution, according to 13.3
[over.match]/2 (invocation of a conversion function for initialization
of an object of a nonclass type from an expression of class type
(13.3.1.5)).

According to 13.3.1.5, [over.match.conv]/1, both conversion functions
are candidate functions. According to 13.3.2, [over.match.viable],
both are viable functions. In particular, there is an implicit
conversion sequence for the first (and only) argument.

The implicit argument is of type A. For one conversion function, the
implicit parameter is of type A&, for the other, it is of type const
A&. So there are two standard conversions to compare
A -> A& (lvalue transformation)
A -> const A& (lvalue transformation, qualification adjustment)

The first standard conversion sequence is better, so the compiler
selects the conversion to char*. The resulting char* then gets
qualification-adjusted to initialize "const char* b".

> Note that, if I remove one const,  e.g.,
> 	operator const char *() { return "";}
> the code no longer warns...

No. In this case, both conversions take an A&, so none of the standard
conversions is better than the other. According to 13.3.3,
[over.match.best]/1, we now check whether one conversion function is
template (neither is), and then we check whether the context is an
initialization by conversion function (it is).

Now we compare the standard conversion sequences converting the result
of the conversion function to the target type. There we have

char* -> const char* (qualification adjustment)
const char* -> const char* (identity conversion)

Identity conversion is better, so we chose operator const char*().

Hope this helps,
Martin

P.S. It is sufficient to send bug reports to
egcs-bugs@egcs.cygnus.com. Duplicates to egcs@egcs.cygnus.com are not
required. In case this was not meant as a bug report, it should not
have been copied to egcs-bugs.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-19 16:01 ` Martin v. Loewis
@ 1999-06-20  5:08   ` Charles Galambos
  1999-06-22  3:09     ` Jason Merrill
  1999-06-30 15:43     ` Charles Galambos
  1999-06-30 15:43   ` Martin v. Loewis
  1 sibling, 2 replies; 8+ messages in thread
From: Charles Galambos @ 1999-06-20  5:08 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

Hi,

I've just tried the pre-release egcs 2.95 compiler on my 
C++ code, and get thousands of warnings that follow the exact
same pattern as below.  Can I ask what the correct solution
to the problem is ?  I prefer to write code that is warning free
with the -Wall switch. As far as I can see I need to include both
functions, one to access a constant object one for non-constant use,
so how do I avoid the warning ?

> > I have trouble understanding why the following fragment:
> 
> I'm not sure what your question is; I'll try to answer it
> anyway. However, comp.std.c++ is a better place for this kind of
> problem.
> 
> > a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
> > a.C:9: warning:   for conversion from `A' to `const char *'
> > a.C:9: warning:   because conversion sequence for the argument is better
> 
> The compiler is right in calling A::operator char *(). 
> 
> This is a case for overload resolution, according to 13.3
> [over.match]/2 (invocation of a conversion function for initialization
> of an object of a nonclass type from an expression of class type
> (13.3.1.5)).
> 
> According to 13.3.1.5, [over.match.conv]/1, both conversion functions
> are candidate functions. According to 13.3.2, [over.match.viable],
> both are viable functions. In particular, there is an implicit
> conversion sequence for the first (and only) argument.
> 
> The implicit argument is of type A. For one conversion function, the
> implicit parameter is of type A&, for the other, it is of type const
> A&. So there are two standard conversions to compare
> A -> A& (lvalue transformation)
> A -> const A& (lvalue transformation, qualification adjustment)
> 
> The first standard conversion sequence is better, so the compiler
> selects the conversion to char*. The resulting char* then gets
> qualification-adjusted to initialize "const char* b".

[...] text removed

Thanks,
Charles Galambos.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-20  5:08   ` Charles Galambos
@ 1999-06-22  3:09     ` Jason Merrill
  1999-06-30 15:43       ` Jason Merrill
  1999-06-30 15:43     ` Charles Galambos
  1 sibling, 1 reply; 8+ messages in thread
From: Jason Merrill @ 1999-06-22  3:09 UTC (permalink / raw)
  To: Charles Galambos; +Cc: Martin v. Loewis, egcs

You could convert to char* first, then const char*.  Or you could add a
non-const operator const char*().

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-20  5:08   ` Charles Galambos
  1999-06-22  3:09     ` Jason Merrill
@ 1999-06-30 15:43     ` Charles Galambos
  1 sibling, 0 replies; 8+ messages in thread
From: Charles Galambos @ 1999-06-30 15:43 UTC (permalink / raw)
  To: Martin v. Loewis; +Cc: egcs

Hi,

I've just tried the pre-release egcs 2.95 compiler on my 
C++ code, and get thousands of warnings that follow the exact
same pattern as below.  Can I ask what the correct solution
to the problem is ?  I prefer to write code that is warning free
with the -Wall switch. As far as I can see I need to include both
functions, one to access a constant object one for non-constant use,
so how do I avoid the warning ?

> > I have trouble understanding why the following fragment:
> 
> I'm not sure what your question is; I'll try to answer it
> anyway. However, comp.std.c++ is a better place for this kind of
> problem.
> 
> > a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
> > a.C:9: warning:   for conversion from `A' to `const char *'
> > a.C:9: warning:   because conversion sequence for the argument is better
> 
> The compiler is right in calling A::operator char *(). 
> 
> This is a case for overload resolution, according to 13.3
> [over.match]/2 (invocation of a conversion function for initialization
> of an object of a nonclass type from an expression of class type
> (13.3.1.5)).
> 
> According to 13.3.1.5, [over.match.conv]/1, both conversion functions
> are candidate functions. According to 13.3.2, [over.match.viable],
> both are viable functions. In particular, there is an implicit
> conversion sequence for the first (and only) argument.
> 
> The implicit argument is of type A. For one conversion function, the
> implicit parameter is of type A&, for the other, it is of type const
> A&. So there are two standard conversions to compare
> A -> A& (lvalue transformation)
> A -> const A& (lvalue transformation, qualification adjustment)
> 
> The first standard conversion sequence is better, so the compiler
> selects the conversion to char*. The resulting char* then gets
> qualification-adjusted to initialize "const char* b".

[...] text removed

Thanks,
Charles Galambos.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-22  3:09     ` Jason Merrill
@ 1999-06-30 15:43       ` Jason Merrill
  0 siblings, 0 replies; 8+ messages in thread
From: Jason Merrill @ 1999-06-30 15:43 UTC (permalink / raw)
  To: Charles Galambos; +Cc: Martin v. Loewis, egcs

You could convert to char* first, then const char*.  Or you could add a
non-const operator const char*().

Jason

^ permalink raw reply	[flat|nested] 8+ messages in thread

* C++ conversion rules ???
  1999-06-19  7:35 C++ conversion rules ??? Marc Espie
  1999-06-19 16:01 ` Martin v. Loewis
@ 1999-06-30 15:43 ` Marc Espie
  1 sibling, 0 replies; 8+ messages in thread
From: Marc Espie @ 1999-06-30 15:43 UTC (permalink / raw)
  To: egcs, egcs-bugs

I have trouble understanding why the following fragment:

struct A {
	operator const char *() const { return "";}
	operator char *() { return "";}
};

A a;
const char *b = a;


will yield

a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
a.C:9: warning:   for conversion from `A' to `const char *'
a.C:9: warning:   because conversion sequence for the argument is better

even after reading the ANSI C++ drafts I have...

Note that, if I remove one const,  e.g.,
	operator const char *() { return "";}
the code no longer warns...

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: C++ conversion rules ???
  1999-06-19 16:01 ` Martin v. Loewis
  1999-06-20  5:08   ` Charles Galambos
@ 1999-06-30 15:43   ` Martin v. Loewis
  1 sibling, 0 replies; 8+ messages in thread
From: Martin v. Loewis @ 1999-06-30 15:43 UTC (permalink / raw)
  To: espie; +Cc: egcs, egcs-bugs

> I have trouble understanding why the following fragment:

I'm not sure what your question is; I'll try to answer it
anyway. However, comp.std.c++ is a better place for this kind of
problem.

> a.C:9: warning: choosing `A::operator char *()' over `A::operator const char *() const'
> a.C:9: warning:   for conversion from `A' to `const char *'
> a.C:9: warning:   because conversion sequence for the argument is better

The compiler is right in calling A::operator char *(). 

This is a case for overload resolution, according to 13.3
[over.match]/2 (invocation of a conversion function for initialization
of an object of a nonclass type from an expression of class type
(13.3.1.5)).

According to 13.3.1.5, [over.match.conv]/1, both conversion functions
are candidate functions. According to 13.3.2, [over.match.viable],
both are viable functions. In particular, there is an implicit
conversion sequence for the first (and only) argument.

The implicit argument is of type A. For one conversion function, the
implicit parameter is of type A&, for the other, it is of type const
A&. So there are two standard conversions to compare
A -> A& (lvalue transformation)
A -> const A& (lvalue transformation, qualification adjustment)

The first standard conversion sequence is better, so the compiler
selects the conversion to char*. The resulting char* then gets
qualification-adjusted to initialize "const char* b".

> Note that, if I remove one const,  e.g.,
> 	operator const char *() { return "";}
> the code no longer warns...

No. In this case, both conversions take an A&, so none of the standard
conversions is better than the other. According to 13.3.3,
[over.match.best]/1, we now check whether one conversion function is
template (neither is), and then we check whether the context is an
initialization by conversion function (it is).

Now we compare the standard conversion sequences converting the result
of the conversion function to the target type. There we have

char* -> const char* (qualification adjustment)
const char* -> const char* (identity conversion)

Identity conversion is better, so we chose operator const char*().

Hope this helps,
Martin

P.S. It is sufficient to send bug reports to
egcs-bugs@egcs.cygnus.com. Duplicates to egcs@egcs.cygnus.com are not
required. In case this was not meant as a bug report, it should not
have been copied to egcs-bugs.

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~1999-06-30 15:43 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-06-19  7:35 C++ conversion rules ??? Marc Espie
1999-06-19 16:01 ` Martin v. Loewis
1999-06-20  5:08   ` Charles Galambos
1999-06-22  3:09     ` Jason Merrill
1999-06-30 15:43       ` Jason Merrill
1999-06-30 15:43     ` Charles Galambos
1999-06-30 15:43   ` Martin v. Loewis
1999-06-30 15:43 ` Marc Espie

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).