g++ 2.95.2 bug

Martin Sebor sebor@roguewave.com
Tue Nov 30 23:39:00 GMT 1999


Thank you for your prompt and detailed response (and an excellent
compiler). I've forwarded it to John Spicer of EDG - I think you might
be interested in his take on the problem. While intuitively I would
agree with him, all I care about is that all compilers behave the same.
So far, out of the 7 major compilers I tried this with, 4 give an error
and 3 compile it fine.

Martin


"Martin v. Loewis" wrote:
> 
> > This is a report of a g++ 2.95.2 bug. I believe the program below should
> > compile and return 0 (it does with edg).
> 
> Thanks for your bug report. I believe g++ is right, which would then
> indicate an error in edg.
> 
> > test.cpp:5: candidates are: int foo<const char[2]>(const char (&)[2])
> > test.cpp:12:                 int foo<const char>(const char *)
> 
> You did not explain why you think g++ is incorrect, let's take it
> step-by-step.
> 
> First, I assume that both functions are indeed viable candidates, with
> template argument deduction deducing const char[2] and const char,
> respectively. If that is questionable, please let me know.
> 
> Now, let's consider the necessary conversion sequences. For the call
> too foo(const char*), an array-to-pointer conversion is needed, with
> no additional conversions.
> 
> For the call to foo(const char(&)[2]), an initialization via direct
> reference binding can be performed, according to 8.5.3/5 (note that
> the character literal is an lvalue which is reference-compatible with
> the parameter type).
> 
> According to 13.3.3.2/3, neither conversion sequence is better than
> the other: both are standard conversion sequences, and neither is a
> proper subsequence of the other (since Lvalue Transformations are
> ignored), both sequences are of Exact Match Rank, neither involves
> qualification conversion, and one of them is not a reference binding.
> 
> According to 13.3.3/2, the call is ill-formed.
> 
> Regards,
> Martin


To : Martin Sebor <sebor at roguewave dot com>
Subject : Re: edg bug(?)
>From : "John H. Spicer" <jhs at edg dot com>
Date : Tue, 30 Nov 1999 15:41:09 -0500
CC : John Pedretti <pedretti at roguewave dot com>,       Daveed Vandevoorde <daveed at edg dot com>,       "J. Stephen Adamczyk" <jsa at edg dot com>
Organization : Edison Design Group
References : <384348B7.B9EFA809@roguewave.com>

Martin Sebor wrote:
> 
> Hello John,
> 
> Attached is a g++ bug report I filed with GNU. The test case passes with
> the evaluation version of edg we have as well as several other major
> vendors' compilers. I'm wondering what your thoughts on the subject are.

It looks like a g++ bug to me.

The analysis done by Martin Loewis is correct as far as it goes, but it
fails to take into account partial ordering.  When two candidates are
indistinguishable for overload resolution purposes, the partial ordering
rules are applied to see if one template should be preferred over another.

These template actually are ordered relative to one another because top
level references are ignored for puposes of partial ordering comparision.
So you end up comparing f(T) with f(T*), and f(T*) is selected as being
more specialized than f(T).

John Spicer
Edison Design Group

> 
> Thanks
> Martin
> 
> ==============================================
>     Martin Sebor, Lead Software Engineer
> C++ Standards Group, Rogue Wave Software, Inc.
>     sebor@roguewave.com   (303) 545-3287
> 
>                                                   
> 
> Subject: Re: g++ 2.95.2 bug
> Date: Tue, 30 Nov 1999 01:00:52 +0100
> From: "Martin v. Loewis" <martin@mira.isdn.cs.tu-berlin.de>
> To: sebor@roguewave.com
> CC: gcc-bugs@gcc.gnu.org, pedretti@roguewave.com, jay@roguewave.com,
>      baus@roguewave.com
> References: < 3841A688.8468C9F1@roguewave.com >
> 
> > This is a report of a g++ 2.95.2 bug. I believe the program below should
> > compile and return 0 (it does with edg).
> 
> Thanks for your bug report. I believe g++ is right, which would then
> indicate an error in edg.
> 
> > test.cpp:5: candidates are: int foo<const char[2]>(const char (&)[2])
> > test.cpp:12:                 int foo<const char>(const char *)
> 
> You did not explain why you think g++ is incorrect, let's take it
> step-by-step.
> 
> First, I assume that both functions are indeed viable candidates, with
> template argument deduction deducing const char[2] and const char,
> respectively. If that is questionable, please let me know.
> 
> Now, let's consider the necessary conversion sequences. For the call
> too foo(const char*), an array-to-pointer conversion is needed, with
> no additional conversions.
> 
> For the call to foo(const char(&)[2]), an initialization via direct
> reference binding can be performed, according to 8.5.3/5 (note that
> the character literal is an lvalue which is reference-compatible with
> the parameter type).
> 
> According to 13.3.3.2/3, neither conversion sequence is better than
> the other: both are standard conversion sequences, and neither is a
> proper subsequence of the other (since Lvalue Transformations are
> ignored), both sequences are of Exact Match Rank, neither involves
> qualification conversion, and one of them is not a reference binding.
> 
> According to 13.3.3/2, the call is ill-formed.
> 
> Regards,
> Martin
> 
>                                                   
> 
> Subject: g++ 2.95.2 bug
> Date: Sun, 28 Nov 1999 15:02:48 -0700
> From: Martin Sebor <sebor@roguewave.com>
> Organization: Rogue Wave Software, Inc.
> To: gcc-bugs@gcc.gnu.org
> CC: John Pedretti <pedretti@roguewave.com>, jay@roguewave.com,
>      baus@roguewave.com
> 
> Hi,
> 
> This is a report of a g++ 2.95.2 bug. I believe the program below should
> compile and return 0 (it does with edg).
> 
> Thanks
> Martin
> 
> $ g++ -v -c test.cpp
> Reading specs from /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/specs
> gcc version 2.95.2 19991024 (release)
>  /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cpp -lang-c++ -v -D__GNUC__=2
> -D__GNUG__=2 -D__GNUC_MINOR__=95 -D__cplusplus -D__ELF__ -Dunix
> -D__i386__ -Dlinux -D__ELF__ -D__unix__ -D__i386__ -D__linux__ -D__unix
> -D__linux -Asystem(posix) -D__EXCEPTIONS -Acpu(i386) -Amachine(i386)
> -Di386 -D__i386 -D__i386__ -Di686 -Dpentiumpro -D__i686 -D__i686__
> -D__pentiumpro -D__pentiumpro__ test.cpp /tmp/ccTs4ze9.ii
> GNU CPP version 2.95.2 19991024 (release) (i386 Linux/ELF)
> #include "..." search starts here:
> #include <...> search starts here:
>  /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../include/g++-3
>  /usr/local/include
> 
> /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/../../../../i686-pc-linux-gnu/include
>  /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/include
>  /usr/include
> End of search list.
> The following default directories have been omitted from the search
> path:
> End of omitted list.
>  /usr/lib/gcc-lib/i686-pc-linux-gnu/2.95.2/cc1plus /tmp/ccTs4ze9.ii
> -quiet -dumpbase test.cc -version -o /tmp/ccyFo499.s
> GNU C++ version 2.95.2 19991024 (release) (i686-pc-linux-gnu) compiled
> by GNU C version 2.95.2 19991024 (release).
> test.cpp: In function `int main()':
> test.cpp:20: call of overloaded `foo (const char[2])' is ambiguous
> test.cpp:5: candidates are: int foo<const char[2]>(const char (&)[2])
> test.cpp:12:                 int foo<const char>(const char *)
> 
> $ cat test.cpp
> 
> template <class T>
> int foo (T&t)
> {
>     return 0;
> }
> 
> template <class T>
> int foo (T*)
> {
>     return 1;
> }
> 
> int main ()
> {
>     char s[] = "a";
>     return foo (*s) + foo (&*s) - foo ("a");
> }


More information about the Gcc-bugs mailing list