1

In GCC, you can create a deprecation warning when someone calls a deprecated function with

void __attribute__((deprecated)) foo() {}

Can you create a similar deprecation warning when someone overrides a virtual method of a class?

curiousguy
  • 8,038
  • 2
  • 40
  • 58
Vortico
  • 2,610
  • 2
  • 32
  • 49
  • 2
    Looks like this is a duplicate of https://stackoverflow.com/questions/49011990/c-deprecation-warning-when-overriding-a-deprecated-virtual-method, which I did not spot before submitting this. The answer appears to be "no, you can't do that", as is the case with many C++-related questions. – Vortico Jun 10 '18 at 05:56

2 Answers2

1

Using [[deprecated]] and [[deprecated(message)]] standard attributes (available since C++14) produce desired effect in Visual Studio both for usage of deprecated method and for attempt to override by issuing C4996 warning (which could be ignored). I cannot speak for other compilers, I expect since this is standard they should comply as well.

class Base
{
public:
    [[deprecated("dont use, deprecated")]] virtual void foo()
    {
    }
};

class Derived : public Base
{
public:
    void foo() override 
    {
    }
};


int main()
{
    Base b;
    b.foo();
}

This will produce 2 warnings, one for the override and one for the attempted use,

Killzone Kid
  • 6,171
  • 3
  • 17
  • 37
0

It will generate an error rather than a warning, but you could add the final specifier to the method declaration in your base class. Then no one could override it.

You could also generate a deprecation message at runtime (rather than compile time) by calling the function and seeing if it runs the base-class implementation or not (by setting a flag in the base-class implementation then checking it after the call).

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • `final` isn't useful here because if I break the API, I might as well remove the function. The only guaranteed location I can call a particular method of a derived class is the constructor of the base class. But if I did that, the derived class wouldn't be initialized yet, so the vtable method might segfault. Not to mention any additional side effects the overridden method might have. – Vortico Jun 10 '18 at 05:52
  • 1
    @Vortico -- calling a virtual member function from a base class constructor won't segfault. It calls the base class's version of the function. – Pete Becker Jun 10 '18 at 06:03
  • 1
    @Vortico: Removing the method completely might silently break clients which overrode it without the `override` specifier. So `final` is better than simple removal. – John Zwinck Jun 10 '18 at 06:12
  • Yes, you're right, my mistake, it calls the base class's method. But then your test of checking would always return a false positive (as the derived class's method is never called.) – Vortico Jun 11 '18 at 04:01
  • Good point about `final`, but it happens in my case that it's mostly guaranteed that callers always use `override` (since everyone's build system uses `-Wsuggest-override -Werror`). – Vortico Jun 11 '18 at 04:02