Easy way find uninitialized member variables

后端 未结 11 929
时光说笑
时光说笑 2020-11-29 22:20

I am looking for an easy way to find uninitialized class member variables.

Finding them in either runtime or compile time is OK.

Currently

相关标签:
11条回答
  • 2020-11-29 22:53

    If you're using Visual Studio, you could compile in debug mode, stop the program in the debugger and look for which variables are initialised to bytes containing 0xCC (stack) or 0xCD (heap).

    Though personally, I'd invest in a static analysis tool for a more thorough approach.

    0 讨论(0)
  • 2020-11-29 22:53

    Consider the following code

    unint.cpp:

    int main()
    {
        int a;
        int b;
        a++;
        b = b + 5;
    
        return 0;
    }
    

    If the code is compiled with following comment, the warning messages shall be displayed.

    g++ -O3 -Wuninitialized unint.cpp

    Note: the -Wuninitialized needs the -O3 option also.

    0 讨论(0)
  • 2020-11-29 22:54

    -Wuninitialized ?

    (This only checks if a variable is used uninitialized, i.e. if

    struct Q { 
      int x, y;
      Q() : x(2) {}
      int get_xy() const { return x*y; }
    };
    

    g++ will warn only when the user calls get_xy() without assigning to y.)

    0 讨论(0)
  • 2020-11-29 22:59

    Beware! Compiler options proposed here are neither reliable, nor version-independent. Consider the simple example:

    class A {
      int a;
    public:
      void mA() {
        printf("haha");
        ++a;
        int g = 2/a;
        printf("%i\n",g);
      }
    };
    
    int main() {
      A a;
      a.mA();
    }
    

    Compiled with g++ -O3 -Weffc++ -Wuninitialized this thing reports uninitialized on gcc versions up to 4.6 inclusive, and passess happily on 4.7 and 4.8 (tested on MacPorts). Then, curiously, if we remove the printf("haha");, both 4.7 and 4.8 suddenly see uninitialized A::a. Clang is a little better, since it somehow assigns rubbish (instead of convenient 0) to uninitialized vars, so you see their disastrous effect easier/sooner.

    I didn't have much luck in spotting the above uninitialized A::a with valgrind either; maybe the gentlement suggesting valgrind could provide appropriate options to spot this error.

    Bottom line: great question, not much reliable solutions at the moment... (the way I see it).

    0 讨论(0)
  • 2020-11-29 23:03

    If you use GCC you can use the -Weffc++ flag, which generates a warnings when a variable isn't initialized in the member initialisation list. This:

    class Foo
    {
      int v;
      Foo() {}
    };
    

    Leads to:

    $ g++ -c -Weffc++ foo.cpp -o foo.o
    foo.cpp: In constructor ‘Foo::Foo()’:
    foo.cpp:4: warning: ‘Foo::v’ should be initialized in the member initialization list
    

    One downside is that -Weffc++ will also warn you when a variable has a proper default constructor and initialisation thus wouldn't be necessary. It will also warn you when you initialize a variable in the constructor, but not in the member initialisation list. And it warns on many other C++ style issues, such as missing copy-constructors, so you might need to clean up your code a bit when you want to use -Weffc++ on a regular basis.

    There is also a bug that causes it to always give you a warning when using anonymous unions, which you currently can't work around other then switching off the warning, which can be done with:

    #pragma GCC diagnostic ignored "-Weffc++"
    

    Overall however I have found -Weffc++ to be incredible useful in catching lots of common C++ mistakes.

    0 讨论(0)
提交回复
热议问题