Skip to content

Extend clang-tidy readability-function-size to allow -1 thresholds and include explicit constructor member initializations count? #131126

Open
@bartlettroscoe

Description

@bartlettroscoe

We are using the clang-tidy checks readability-function-cognitive-complexity and readability-function-size to extract function metrics and produce function metrics data as JSON (by scrapping clang-tidy output) that produces nice metrics like:

  {
    "name": "ArrayTools_Test04",
    "type": "function",
    "location": "packages/intrepid2/unit-test/Shared/ArrayTools/test_04.hpp:46:9",
    "code-line": "int ArrayTools_Test04(const bool verbose) {",
    "cognitive-complexity": 968,
    "nesting-level": 7,
    "num-lines": 3656,
    "num-statements": 5201,
    "num-branches": 422,
    "num-parameters": 1,
    "num-variables": 943
  }

by setting all the thresholds to 0 with the clang-tidy config file:

CheckOptions:
  - key: readability-function-cognitive-complexity.Threshold
    value: '0'
  - key: readability-function-cognitive-complexity.DescribeBasicIncrements
    value: true
  - key: readability-function-cognitive-complexity.IgnoreMacros
    value: true
  - key: readability-function-size.LineThreshold
    value: '0'
  - key: readability-function-size.StatementThreshold
    value: '0'
  - key: readability-function-size.BranchThreshold
    value: '0'
  - key: readability-function-size.ParameterThreshold
    value: '0'
  - key: readability-function-size.NestingThreshold
    value: '0'
  - key: readability-function-size.VariableThreshold
    value: '0'

With this, we can see all functions that have non-zero lines, statements, or parameters. (And after #131040 is addressed, we will be able to see these metrics for constructors and lambda functions as well.)

But even with #131040 addressed, we still will not be able to see functions that have zero lines, zero statements, and zero parameters. What functions have zero lines, zero statements, and zero parameters? => 1) Constructors like:

  SomeClass():
    var1_(<val1>),
    val2_(<val2>),
    val3_(<val3>),
    val4_(<val4>)
    {}

and 2) function overrides for no-ops like:

   int someFunc() override {};

If we could have the readability-function-size checks allow for -1 thresholds, then it would produce output for all functions.

Also, explicit constructor member initializations are code that needs to be maintained, just like variable initialization code inside of a function, so it would be great if the readability-function-size check would report on the number of explicit constructor member initialization counts. This could be reported like:

<source>:<line>:<col>: warning: function 'SomeClass' exceeds recommended size/complexity thresholds [readability-function-size]
  <line> |   SomeClass():
         |   ^
<source>:<line>:<col>: note: 4 member initializers (threshold 0)

Making these changes would have several advantages:

  1. By setting the thresholds to -1, we could use readability-function-size to provide a listing of all functions in a C++ code base and see how many functions have zero parameters, zero statements, etc. (Even non-constructor functions with zero parameters and zero statements represent code that has to be maintained.)
  2. Constructor variable initializations are real code, just like variable initializations inside of a function, and need to be considered when considering the size of a function implementation.

NOTE: Even though there is no executable code associated with functions with zero statements, there is executable code for constructor member initializers.

NOTE: To expand on our code metrics, we would really love to see clang-tidy add checks for the size of C++ classes like number of data members (public, protected, private, static, etc.), number of member functions (public, protected, private, constructors, virtual, override, etc.), number of typedefs/using declarations (public, protected, private, etc.), etc. Currently, the only check that I can see that provides some visibility into class metrics would be misc-non-private-member-variables-in-classes. (I will create a separate issue for that request.)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions