stdcxx-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Travis Vitek (JIRA)" <j...@apache.org>
Subject [jira] Issue Comment Edited: (STDCXX-605) [IBM XLC++] errors compiling dynatype.cpp
Date Wed, 19 Dec 2007 02:49:43 GMT

    [ https://issues.apache.org/jira/browse/STDCXX-605?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12553208
] 

vitek edited comment on STDCXX-605 at 12/18/07 6:49 PM:
---------------------------------------------------------------

In the failure you mention, the conversion we want is to `const int&'. The conversion
operator that gets invoked is the non-const `operator T&'  with 'T' being 'const int'.
That conversion operator calls the non-const retrieve(), which keeps the const and looks in
the static dynatype::map<const int> for a value. We should be looking in dynatype::map<int>,
but the const is not being stripped.

Consider the following...

struct S
{
private:
    template <class T> int g (T*) { return 0; }
    template <class T> int g (const T*) const { return 1; }
public:
    template <class T> int f () { return g ((T*)0); }
};

int main ()
{
    const int a = S().f<int>();
    const int b = S().f<const int>();

    return (a << 1) | b;
}

I believe that the expected result is 0. When compiling the S().f<const int>(), I see
a few candidate functions for overload resolution. Given that the overload resolution system
treats member functions as if they were free functions with a correctly cv-qualified implicit
object parameter, the candidates would seem to be

    int S_g(S&, int*);
    int S_g(S&, const int*);

from the first template, and 

    int S_g(const S&, const int*);

from the second. The actual type of the call is

    ??? S_g(S&, const int*);

So the best match is easily selected, and the result is a call to the non-const 'g' template,
which leaves the const on the template type T instead of stripping it like we want.

Continuing with the example, I see a few options. We could make both 'g' overloads share the
same constness. If we make them have the same constness, then the overload resolution chooses
the best match based on the explicit parameter type, and then discards const as we want. The
disadvantage of this is that we would either have two const overloads of 'g' [which you didn't
appear to like], or we can have two non-const overloads and cast away const when calling from
a const member function. A third option would be to make both 'g' overloads into non-member
functions that takes const S* [essentially the same as making both members const], but that
would require some code rearranging.

Personally I thought that the two const retrieve() overloads was the simplest and cleanest
solution [stdcxx-605-v2.patch]. The most recent patch involves changing fewer lines of code
in the example, but it leaves a nasty static/const cast [stdcxx-605-v1.patch].

      was (Author: vitek):
    In the failure you mention, the conversion we want is to `const int&'. The conversion
operator that gets invoked is the non-const `operator T&'  with 'T' being 'const int'.
That conversion operator calls the non-const retrieve(), which keeps the const and looks in
the static dynatype::map<const int> for a value. We should be looking in dynatype::map<int>,
but the const is not being stripped.

Consider the following...

struct S
{
private:
    template <class T> int g (T*) { return 0; }
    template <class T> int g (const T*) const { return 1; }
public:
    template <class T> int f () { return g ((T*)0); }
};

int main ()
{
    const int a = S().f<int>();
    const int b = S().f<const int>();

    return (a << 1) | b;
}

I believe that the expected result is 0. When compiling the S().f<const int>(), I see
a few candidate functions for overload resolution. Given that the overload resolution system
treats member functions as if they were free functions with a correctly cv-qualified implicit
object parameter, the candidates would seem to be

    int S_g(S&, int*);
    int S_g(S&, const int*);

from the first template, and 

    int S_g(const S&, int*);
    int S_g(const S&, const int*);

from the second. The actual type of the call is

    ??? S_g(S&, const int*);

So the best match is easily selected, and the result is a call to the non-const 'g' template,
which leaves the const on the template type T instead of stripping it like we want.

Continuing with the example, I see a few options. We could make both 'g' overloads share the
same constness. If we make them have the same constness, then the overload resolution chooses
the best match based on the explicit parameter type, and then discards const as we want. The
disadvantage of this is that we would either have two const overloads of 'g' [which you didn't
appear to like], or we can have two non-const overloads and cast away const when calling from
a const member function. A third option would be to make both 'g' overloads into non-member
functions that takes const S* [essentially the same as making both members const], but that
would require some code rearranging.

Personally I thought that the two const retrieve() overloads was the simplest and cleanest
solution [stdcxx-605-v2.patch]. The most recent patch involves changing fewer lines of code
in the example, but it leaves a nasty static/const cast [stdcxx-605-v1.patch].
  
> [IBM XLC++] errors compiling dynatype.cpp
> -----------------------------------------
>
>                 Key: STDCXX-605
>                 URL: https://issues.apache.org/jira/browse/STDCXX-605
>             Project: C++ Standard Library
>          Issue Type: Bug
>          Components: Examples
>    Affects Versions: 4.2.0
>         Environment: XLC++ 6.0 through 9.0/AIX 5.3
>            Reporter: Martin Sebor
>            Assignee: Travis Vitek
>             Fix For: 4.2.1
>
>         Attachments: stdcxx-605-out.patch, stdcxx-605-v1.patch, stdcxx-605-v2.patch
>
>
> The dynatype.cpp example program fails to compile with IBM XLC++ 9.0 on AIX with ethe
following errors:
> xlCcore_r -c -I$(TOPDIR)/include/ansi    -I$(TOPDIR)/include -I$(BUILDDIR)/include -I$(TOPDIR)/examples/include
 -O -Q     -qtemplateregistry=dynatype.ti $(TOPDIR)/examples/tutorial/dynatype.cpp
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 203.27: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "int".
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 209.30: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "double".
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 215.30: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "double".
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 222.35: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "const char *".
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 228.35: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "const char *".
> "$(TOPDIR)/examples/tutorial/dynatype.cpp", line 238.28: 1540-0216 (S) An expression
of type "dynatype" cannot be converted to type "char".
> gmake: *** [dynatype.o] Error 1

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


Mime
View raw message