No compiler warning for ‘const’ pointers of non POD types when overriding a method

No compiler warning for ‘const’ pointers of non POD types when overriding a method


7

An example where one is overriding POD return type without const in the derived class:

struct B1
{
    virtual const int* f();
};

struct D1 : B1
{
    int* f() override;
};

Compilers like Clang and GCC raise a warning:

invalid covariant return type for ‘virtual int* D1::f()’

When same scenario is applied but return type is some struct/class, no warning is raised:

struct S
{
};

struct B2
{
    virtual const S* f();
};

struct D2 : B2
{
    S* f() override;
};

I compiled this on different compilers and versions (Clang and GCC).
I would have expected similar warning when struct/class pointer is returned in the derived class when not using const declaration.

Share
Improve this question

1

1 Answer
1

Reset to default


5

The behaviour you observe is consistent with the Standard. From this Draft C++17 Standard#:

13.3 Virtual functions ┬а┬а┬а┬а┬а [class.virtual]

тАж
8 ┬а┬а┬а 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:

(8.1) ┬а┬атАФ both are
pointers to classes, both are lvalue references to classes, or both
are rvalue references to classes
(8.2) ┬а┬атАФ 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
(8.3) ┬а┬атАФ 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.

So, in your second case, all three of the above criteria are met. Note that 8.3 is true because the pointers returned are not cv-qualified тАУ the const refers to the pointed-to object, not the pointer itself. If you instead declare the base class function as virtual S* const f(); then the derived class version you have will no longer be valid. Further, the return type in your derived class function is less cv-qualified than in the base class; swapping the definitions so that the base class is virtual S* f(); and the derived is const S* f() override; will also make it invalid.

However, in your first snippet, the returned type of the function does not meet the 8.1 criterion (int is not a class); thus, in order to be a valid override, its return type must be identical to that of the base class version.


# The text hasn’t changed significantly in the latest, online draft.

Share
Improve this answer

2

  • Interestingly, removing override still leaves OP's code with a hard error, instead of silently not overriding the function.

    – HolyBlackCat

    11 hours ago

  • 1

    @HolyBlackCat depends. Some compilers whine about incorrect ambigous overloading in that case (function overloads can't differ by return type alone). Once upon a time I believed that this cryptic message alone was the reason for override keyword as an extension.

    – Swift – Friday Pie

    6 hours ago




Your Answer


Post as a guest

Required, but never shown


By clicking тАЬPost Your AnswerтАЭ, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged

or ask your own question.

Leave a Reply

Your email address will not be published. Required fields are marked *