What are the dangers of uninitialised variables?

前端 未结 4 1485
-上瘾入骨i
-上瘾入骨i 2021-01-18 20:38

In a program I am writing I currently have several uninitialised variables in my .h files, all of which are initialised at run-time. However, in Visual Studio it warns me ev

4条回答
  •  天涯浪人
    2021-01-18 21:10

    There are two parts to this question: first is reading uninitialized variables dangerous and second is defining variables uninitialized dangerous even if I make sure I never access uninitialized variables.

    What are the dangers of accessing uninitialized variables?

    With very few exceptions, accessing an uninitialized variable makes the whole program have Undefined Behavior. There is a common misconception (which unfortunately is taught) that uninitialized variables have "garbage values" and so reading an uninitialized variable will result in reading some value. This is completely false. Undefined Behavior means the program can have any behavior: it can crash, it can behave as the variable has some value, it can pretend the variable doesn't even exist or all sorts of weird behaviors.

    For instance:

    void foo();
    void bar();
    
    void test(bool cond)
    {
        int a; // uninitialized
    
        if (cond)
        {
            a = 24;
        }
    
        if (a == 24)
        {
            foo();
        }
        else
        {
            bar();
        }
    }
    

    What is the result of calling the above function with true? What about with false?

    test(true) will cleary call foo().

    What about test(false)? If you answer: "Well it depends on what garbage value is in variable a, if it is 24 it will call foo, else it will call bar" Then you are completely wrong.

    If you call test(false) the program accesses an uninitialized variable and has Undefined Behavior, it is an illegal path and so the compilers are free to assume cond is never false (because otherwise the program would be illegal). And surprise surprise both gcc and clang with optimizations enabled actually do this and generate this assembly for the function:

    test(bool):
            jmp     foo()
    

    So don't do this! Never access uninitialized variable! It is undefined behavior and it's much much worse than "the variable has some garbage value". Furthermore, on your system could work as you expect, on other systems or with other compiler flags it can behave in unexpected ways.

    What are the dangers of defining uninitialized variables if I make sure I always initialize them later, before accessing them?

    Well, the program is correct from this respect, but the source code is prone to errors. You have to mentally burden yourself with always checking if somewhere you actually initialized the variable. And if you did forget to initialize a variable finding the bug will be difficult as you have a lot of variables in your code who are defined uninitialized.

    As opposed, if you always initialize your variables you and the programmers after you have a much much easier job and ease of mind.

    It's just a very very good practice.

提交回复
热议问题