Search code examples
c++clang-tidy

How to avoid clang-tidy warnings about uninitialized variables


I am looking for the best way to avoid cppcoreguidelines-init-variables warnings with clang-tidy.

std::istringstream in(line);
float x, y, z, rotx, roty, rotz;
in >> x >> y >> z >> rotx >> roty >> rotz;

-> variable 'x' is not initialized, variable 'y' is not initialized, ...

double min_intensity, max_intensity;    
cv::Point point_min, point_max;
cv::minMaxLoc(input, &min_intensity, &max_intensity, &point_min, &point_max, elliptic_mask_around_center);

-> variable 'min_intensity' is not initialized, ...

I could assign a value for x, y, ... and min_intensity and max_intensity, but I do not see why I should do it.

What would be the best way to avoid this warning?

float x = 0.F; // initialize to a value, but 6 lines, and it makes no sense because x is never 0
float x = NAN; // works but 6 lines, and needs <cmath> inclusion
float x, y, z, rotx, roty, rotz; // NOLINT [not very practical, and means the warning is a false positive]

Thank you for your help.


Solution

  • In general you should initialize variables always because reading from an uninitialized variable is undefined behavior.

    When extraction from the stream fails then since C++11 a 0 is assigned. However, this is only the case as long as the stream is not in a fail state. Hence, when reading x fails then x will have a value of 0 but the others will have an indetermindate value.

    You should always check if extraction succeded:

    if (in >> x >> y >> z >> rotx >> roty >> rotz) { 
         // use x,y,z,rotx,roty,rotz
    }
    

    And if you want to use part of the input even in case extraction fails at some point, you should read them seperately:

    if (in >> x) {
         // use x
    }
    if (in >> y) {
         // use y
    }
    // ...
    

    If you do that, the initialization is strictly speaking not necessary. However, reading from a stream is way more expensive than initializing a variable, so to be consistent (see eg here) I would suggest to initialize them anyhow. Don't worry about more lines of code, a common recommendation is to declare a single variable per line anyhow (see eg here):

    std::istringstream in(line);
    float x = 0.0;
    float y = 0.0;
    float rotx = 0.0;
    float roty = 0.0;
    float rotz = 0.0;
    if (in >> x >> y >> z >> rotx >> roty >> rotz) {
         // extraction succeeded
    } else {
         // extraction failed
    }