Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cleanly suppress gcc's `final` suggestion warnings (`-Wsuggest-final-types` and `-Wsuggest-final-methods`)

I like compiling my code using -Wsuggest-final-types and -Wsuggest-final-methods in order to be warned about opportunities where the final keyword could be used to allow the compiler to optimize more aggressively.

Sometimes, though, the suggestions are incorrect - for example, I have a class Base with a virtual ~Base() destructor that is used polymorphically in another project, and gcc suggests me that Base could be marked as final.

Is there a way to "cleanly" tell the compiler that Base is used polymorphically and should not be marked as final?

The only way I can think of is using #pragma directives, but I find it makes the code cluttered and hard to read.

Ideally, I'm looking for a non-final keyword or attribute that can be prepended/appended to the class/method declaration.

like image 583
Vittorio Romeo Avatar asked Feb 10 '16 09:02

Vittorio Romeo


1 Answers

I came up with a macro-based solution that I really don't like, but it solves the problem.

#define MARK_NONFINAL_CLASS(base)                              \
    namespace SOME_UNIQUE_NAME                                 \
    {                                                          \
        struct [[unused]] temp_marker final : base             \
        {                                                      \
        };                                                     \
    }

#define MARK_NONFINAL_METHOD(base, return_type, method)                  \
    namespace SOME_UNIQUE_NAME                                           \
    {                                                                    \
        struct [[unused]] temp_marker final : base                       \
        {                                                                \
            inline return_type [[unused]] method override {}             \
        };                                                               \
    }

Usage:

class Base
{
    virtual ~Base()
    {
    }

    virtual int a(float f)
    {
    }
    virtual void b(double)
    {
    }
};

MARK_NONFINAL_CLASS(Base)
MARK_NONFINAL_METHOD(Base, int, a(float))
MARK_NONFINAL_METHOD(Base, void, b(double))
like image 169
Vittorio Romeo Avatar answered Nov 15 '22 05:11

Vittorio Romeo