tags:

views:

92

answers:

1

$10.3/5

"The return type of an overriding function shall be either identical to the return type of the overridden function or covariant with the classes of the functions. If a function D::f overrides a function B::f, the return types of the functions are covariant if they satisfy the following criteria:

— both are pointers to classes or references to classes98)

— the class in the return type of B::f is the same class as the class in the return type of D::f, or is an unambiguous and accessible direct or indirect base class of the class in the return type of D::f

both pointers or references have the same cv-qualification and the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.

struct A{};
struct B : A{};

struct X{
    virtual const A * const f(){return 0;}
};

struct Y : X{
    virtual const B * volatile f(){return 0;}
};

int main(){
    Y b;
    X &r = b;
    r.f();
}

I wrote the above experimental code and find Comeau's error/warning to be inconsitent. The warning in Line 9 seems to indicate that cv qualifier in return type is meaningless. And it is this very reason which leads to the code being ill-formed.

"ComeauTest.c", line 5: warning: type qualifier on return type is meaningless
virtual const A * const f(){return 0;}
                  ^

"ComeauTest.c", line 9: warning: type qualifier on return type is meaningless
virtual const B * volatile f(){return 0;}
                  ^

"ComeauTest.c", line 9: error: return type is not identical to nor covariant with
      return type "const A *const" of overridden virtual function function
      "X::f"
virtual const B * volatile f(){return 0;}
                           ^

So the question is, is Comeau right in giving the "warning" message at Line 9? I know that is an implementation defined behavior and Comeau is just trying to be nice. But in this case, it is at the best confusing.

+2  A: 

The warnings on lines 5 and 9 that the "type qualifier on return type is meaningless" are because non-class type rvalues are never cv-qualified.

Since the result of a function that returns by value is an rvalue and a pointer is a non-class type, the returned pointer is not cv-qualified, even if the return type says that it is.

This warning has nothing to do with covariance. The following function would cause the same warning:

int* volatile f() { return 0; }

As for the cited text from 10.3/5:

both pointers or references have the same cv-qualification

This is referring to the top-level qualification of the return type (that is, the volatile in const int* volatile). While the top-level qualification is meaningless, it does affect the type of the function, so given the declaration of f above, this snippet is incorrect:

int* (*q)() = f; // error:  can't convert int* volatile (*)() to int* (*)()

Likewise, if the top-level cv-qualification of the return type in the derived class member function does not match the top-level cv-qualification of the return type in the base class, the derived class member function does not override the base class member function.

the class type in the return type of D::f has the same cv-qualification as or less cv-qualification than the class type in the return type of B::f.

This is referring to the qualification of the class type of the return value (that is, the const in const int* volatile). This rule means that the qualification of the return type in the derived class member function must be equal to or less than that of return type of the base class member function that it overrides.

James McNellis
@James McNellis: How do I interpret the two 'bolded' portions in the third bullet of the conditions for covariance, specifically the second part of the and condition?
Chubsdad
@James McNellis: If it 'does affect the type of the function', I think the warning message from Comeau is probably not correct in this context. Or is it not?
Chubsdad
@chubsdad: There is a difference between the return type of `f` (which is `int* volatile`) and the type of the rvalue function call expression `f()` (which is `int*`). Comeau is warning you that the top-level cv-qualifier is meaningless for the latter case.
James McNellis
@chubsdad: For real code, it's generally recommended _not_ to cv-qualify at the top level a non-class return type. It can cause problems, for example [with template instantiation](http://stackoverflow.com/questions/2926319/when-does-a-const-return-type-interfere-with-template-instantiation).
James McNellis