[clazy] [Bug 408038] New: Add a family of checks for "Qt value classes"

Giuseppe D'Angelo bugzilla_noreply at kde.org
Tue May 28 17:50:36 BST 2019


https://bugs.kde.org/show_bug.cgi?id=408038

            Bug ID: 408038
           Summary: Add a family of checks for "Qt value classes"
           Product: clazy
           Version: unspecified
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: unassigned-bugs at kde.org
          Reporter: dangelog at gmail.com
                CC: smartins at kde.org
  Target Milestone: ---

>From my experience at developing Qt itself (and Qt-based applications), here's
a suggestion for a family of checks.

We need to establish a definition for a "value class". In Qt: any class with a
public copy constructor. Move-only classes can also be considered value classes
but they're very rare in Qt.

The value classes that are interesting for us are either thin abstractions
(QRect, QPoint) or thick abstractions (QString, QFont). The main feat thick
abstractions in Qt are pimpled; thin abstractions have multiple non-pointer
data members right into the class itself. 

(RAII classes, another category of value classes, usually have
pointer/references data members. For more info, cf's Marc Mutz' talk at
MeetingC++. Runtime polymorphic classes shouldn't be copiable in the first
place, so they're not value classes for us.)


So, somehow, a thick abstraction is detectable due to the presence of just one
data member of type QSharedDataPointer / QExplictlySharedDataPointer etc. If
this proves to be hard, we can always have an attribute.


For any value class which is public API (not sure how to enforce that; file
name in which the declaratino appears?), check that:

* QVariant::fromValue(obj); compiles (implying either builtin support in
QVariant and/or Q_DECLARE_METATYPE exists)
* Q_DECLARE_TYPEINFO / QTypeInfo specialization exists for it. Thin classes are
usually primitive, and thick classes are usually movable.
* qDebug() << obj; compiles
* QDataStream ds; ds << obj; compiles
* qHash(obj); compiles (and possibly is noexcept)
* The class has a noexcept member swap 
* A noexcept swap(obj1, obj2) overload in the class' namespace exists
* std::hash<Class>{}(obj) compiles (and possibly is noexcept)
* The class is final


For thin abstractions also check that:

* The class itself is NOT exported; only individual, outofline members are
* The class follows the rule of 0
* Constructors are noexcept and constexpr
* Destruction is trivial (= the class is a literal type)
* Any function defined inline is also constexpr; 
* Any function defined inline is also noexcept -- this may give false
positives. In general it's impossible to check due to Lakos' rule; I'd warn
nonetheless and have users annotate with noexcept(false).


For thick abstractions also check that:

* The class is exported
* The class follows the rule of 5 (at the moment Qt cannot implement move
constructors, though; a resolution is coming)

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the Unassigned-bugs mailing list