[Bug c++/53415] New: problematic error message for ambiguity

zeratul976 at hotmail dot com gcc-bugzilla@gcc.gnu.org
Sat May 19 01:14:00 GMT 2012


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=53415

             Bug #: 53415
           Summary: problematic error message for ambiguity
    Classification: Unclassified
           Product: gcc
           Version: 4.8.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned@gcc.gnu.org
        ReportedBy: zeratul976@hotmail.com


Consider the following code:


struct string
{
    string(char*);
};

template <typename T>
void operator+(const string&, const T&);

template <int>
struct S {};

template <typename>
struct T
{
    enum {value = 0};
};

template <class X>
S<0 + T<X>::value> foo(X);

int main()
{
    foo(1);
}


Trunk gives the following error message:


test.cpp: In function 'int main()':
test.cpp:23:10: error: no matching function for call to 'foo(int)'
     foo(1);
          ^
test.cpp:23:10: note: candidate is:
test.cpp:19:20: note: template<class X> S<(0 + T< <template-parameter-1-1>
>::value)> foo(X)
 S<0 + T<X>::value> foo(X);
                    ^
test.cpp:19:20: note:   template argument deduction/substitution failed:
test.cpp: In substitution of 'template<class X> S<(0 + T<
<template-parameter-1-1> >::value)> foo(X) [with X = int]':
test.cpp:23:10:   required from here
test.cpp:19:20: warning: ISO C++ says that these are ambiguous, even though the
worst conversion for the first is better than the worst conversion for the
second: [enabled by default]
test.cpp:19:20: note: candidate 1: operator+(int, int) <built-in>
test.cpp:7:6: note: candidate 2: void operator+(const string&, const T&) [with
T = T<int>::<anonymous enum>]
 void operator+(const string&, const T&);
      ^


I think there are several problems with this error message:

1. Template argument deduction/substitution is failing because of a *warning*?
The following reduced example:

    struct string
    {
        string(char*);
    };

    template <typename T>
    void operator+(const string&, const T&);

    struct T
    {
        enum {value = 0};
    };

    int main()
    {
        return 0 + T::value; 
    }

gives a similar warning but no errors. It is inconsistent for an ambiguity to
cause just a warning in one case, and failure of template argument
deduction/substitution in another.

2. There is no caret diagnostic associated with the "ISO C++ says that these
are ambiguous" warning, so it's difficult to tell what "these" are. (We can
infer from the candidates being operator+, but there could have been many uses
of operator+ in that expression, and only one of them ambiguous, so it would be
nice to have a caret pointing to that one).

3. GCC 4.7 compiles the original example fine. Assuming this change in
behaviour is intentional, it should be documented on the 4.8 changes page
because it breaks existing code.



More information about the Gcc-bugs mailing list