public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* New c++ bug with conversion operators?
@ 1998-05-06 16:13 Benjamin Redelings I
  1998-05-08 19:52 ` Martin von Loewis
  1998-05-25 13:43 ` PATCH for " Mark Mitchell
  0 siblings, 2 replies; 3+ messages in thread
From: Benjamin Redelings I @ 1998-05-06 16:13 UTC (permalink / raw)
  To: egcs

Hi!, I recently went from the 980315 snapshot to 19980502.  gcc still
compiles the kernel OK with -mpentiumpro -O12 -fstrength-reduce, but I
have a new problem with one of my C++ projects.

g++ now appears not to want 'const' conversion operators any more...
Here is my sample code:
---------------test.C------------------
struct string
{
  char* location;
  int length;

  operator const char*() const{return location;}
  /*  operator const char*() {return location;} */
  operator char*() {return location;}
};

main() {
  int i;
  string s1;
  const string s2=s1;

  i=strlen(s1);
  i=strlen(s2);
}
--------------end test.C--------------
Here is the text of the warnings:
telomere:~/devel/Psh.0.4.6.8> make test
g++ -fno-rtti -fno-exceptions -Wall -g -O13 -DNDEBUG -mpentiumpro
-I../include -fno-rtti -fno-exceptions   test.C   -o test
test.C: In function `int main()':
test.C:16: warning: choosing `string::operator char *()' over
`string::operator const char *() const'
test.C:16: warning:   for conversion from `string' to `const char *'
test.C:16: warning:   because conversion sequence for `this' argument is
better
test.C:16: warning: choosing `string::operator char *()' over
`string::operator const char *() const'
test.C:16: warning:   for conversion from `string' to `const char *'
test.C:16: warning:   because conversion sequence for `this' argument is
better


	This seems rather strange to me...the second 'const' in the declaration
of
'operator const char*()' just means that "*this" will not be changed
during the conversion (nor will be changed afterwards, with the info
provided by the conversion).  But g++ is saying that it won't use this
operator on 's1' because 's1' wasn't declared const!  That is
irrelevant.
	If it is possible to consider the type that s1 is being cast to by
strlen, then it should consider that instead and convert to 'const
char*'.

If you uncomment the second operator definition, the warning goes away. 
Wierd.  Am I perhaps coding this in the wrong way?  That DOES seem likea
strange way to code, but AFAIK C++ requires it.

-BenRI

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

* Re: New c++ bug with conversion operators?
  1998-05-06 16:13 New c++ bug with conversion operators? Benjamin Redelings I
@ 1998-05-08 19:52 ` Martin von Loewis
  1998-05-25 13:43 ` PATCH for " Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Martin von Loewis @ 1998-05-08 19:52 UTC (permalink / raw)
  To: bredelin; +Cc: egcs

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 2048 bytes --]

> struct string
> {
>   char* location;
>   int length;
> 
>   operator const char*() const{return location;}
>   /*  operator const char*() {return location;} */
>   operator char*() {return location;}
> };
> 
> main() {
>   int i;
>   string s1;
>   const string s2=s1;
> 
>   i=strlen(s1);
>   i=strlen(s2);
> }

Has anybody had a chance to look at this report? I assume that
strlen in the example is 

int strlen(const char*);

which makes me believe that the following analysis matches the
standard.

In order to call strlen(s2), an implicit convertion from string
to const char* is needed. There are two such sequences:

string -> char* -> const char*
string -> const string -> const char*

According to [over.ics.user], both are userdefined conversion
sequences. Therefore, ranking is based on [over.ics.rank]/3, last
bullet. There it says

>> User­defined conversion sequence U1 is a better conversion sequence
>> than another user­defined conversion sequence U2 if they contain
>> the same user­defined conversion function or constructor and if the
>> second standard conversion sequence of U1 is better than the second
>> standard conversion sequence of U2.

Since these two sequences do not contain the same user-defined
conversion function, there is not a single one that is better than the
other. Therefore, this conversion is an ambiguous one as defined in
[over.best.ics]/10. Since the function selected from the candidate
list is one that requires the conversion, the above program is
ill-formed. So egcs is right to produce diagnostics.

What puzzles me is that the addition of the third operation silences
g++. This give the additional conversion

string -> const char*

which has an identity conversion as second standard
conversion. However, it still uses a different user-defined function
than any of the other two sequences, and therefore does not rank
better than any of these.

So I believe that egcs should still produce diagnostics, and the
program should be changed to use explicit conversions.

Regards,
Martin

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

* PATCH for Re: New c++ bug with conversion operators?
  1998-05-06 16:13 New c++ bug with conversion operators? Benjamin Redelings I
  1998-05-08 19:52 ` Martin von Loewis
@ 1998-05-25 13:43 ` Mark Mitchell
  1 sibling, 0 replies; 3+ messages in thread
From: Mark Mitchell @ 1998-05-25 13:43 UTC (permalink / raw)
  To: bredelin; +Cc: egcs, Jason Merrill

  struct string
  {
    char* location;
    int length;

    operator const char*() const{return location;}
    /*  operator const char*() {return location;} */
    operator char*() {return location;}
  };

  main() {
    int i;
    string s1;
    const string s2=s1;

    i=strlen(s1);
    i=strlen(s2);
  }
  --------------end test.C--------------
  Here is the text of the warnings:
  telomere:~/devel/Psh.0.4.6.8> make test
  g++ -fno-rtti -fno-exceptions -Wall -g -O13 -DNDEBUG -mpentiumpro
  -I../include -fno-rtti -fno-exceptions   test.C   -o test
  test.C: In function `int main()':
  test.C:16: warning: choosing `string::operator char *()' over
  `string::operator const char *() const'
  test.C:16: warning:   for conversion from `string' to `const char *'
  test.C:16: warning:   because conversion sequence for `this' argument is
  better
  test.C:16: warning: choosing `string::operator char *()' over
  `string::operator const char *() const'
  test.C:16: warning:   for conversion from `string' to `const char *'
  test.C:16: warning:   because conversion sequence for `this' argument is
  better

Actually, g++ is doing the right thing here.  The overloading rules 
say (in [over.match.conv]):

  The argument list has one argument, which is the initializer expres-
  sion.  [Note: this argument will be compared against the implicit
  object parameter of the conversion functions.  ]

So, the fact that `s1' is not const does matter.  This is somewhat
surprising behavior, which is why g++ warns.

There's no reason for it to warn twice, though.  (And that might have
confused into thinking the second warning is about `s2', which it
isn't).  Jason, is the following patch OK?

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-05-25  Mark Mitchell  <mark@markmitchell.com>

	* call.c (tourney): Don't do any extra comparisons.

Index: call.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/call.c,v
retrieving revision 1.80
diff -c -p -r1.80 call.c
*** call.c	1998/05/24 23:55:15	1.80
--- call.c	1998/05/25 18:36:24
*************** tourney (candidates)
*** 4389,4394 ****
--- 4389,4395 ----
  {
    struct z_candidate *champ = candidates, *challenger;
    int fate;
+   int champ_compared_to_predecessor = 0;
  
    /* Walk through the list once, comparing each current champ to the next
       candidate, knocking out a candidate or two with each comparison.  */
*************** tourney (candidates)
*** 4405,4423 ****
  	      champ = challenger->next;
  	      if (champ == 0)
  		return 0;
  	    }
  	  else
! 	    champ = challenger;
  
  	  challenger = champ->next;
  	}
      }
  
    /* Make sure the champ is better than all the candidates it hasn't yet
!      been compared to.  This may do one more comparison than necessary.  Oh
!      well.  */
  
!   for (challenger = candidates; challenger != champ;
         challenger = challenger->next)
      {
        fate = joust (champ, challenger, 0);
--- 4406,4429 ----
  	      champ = challenger->next;
  	      if (champ == 0)
  		return 0;
+ 	      champ_compared_to_predecessor = 0;
  	    }
  	  else
! 	    {
! 	      champ = challenger;
! 	      champ_compared_to_predecessor = 1;
! 	    }
  
  	  challenger = champ->next;
  	}
      }
  
    /* Make sure the champ is better than all the candidates it hasn't yet
!      been compared to.  */
  
!   for (challenger = candidates; 
!        challenger != champ 
! 	 && !(champ_compared_to_predecessor && challenger->next == champ);
         challenger = challenger->next)
      {
        fate = joust (champ, challenger, 0);

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

end of thread, other threads:[~1998-05-25 13:43 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-05-06 16:13 New c++ bug with conversion operators? Benjamin Redelings I
1998-05-08 19:52 ` Martin von Loewis
1998-05-25 13:43 ` PATCH for " Mark Mitchell

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).