0

I have some code performing a summation (below). It is called from another file. However, sum was not initialized, caused a bug but GCC (v11.1) did not give a compiler error.

I have these flags set:

-Wall -Wextra -pedantic -march=native -Werror=return-type -Wswitch-enum -Wconversion -Werror=attributes -Werror=unused-variable -Werror=unused-parameter -Werror=unused-result -Werror=address -Werror=unused-function -Werror=unused-but-set-parameter -Werror=uninitialized -g -O0

  1. Why did I not get an error for this uninitialized local variable/what flag do I need to set?

  2. Are there any other useful flags I should set? (I'm aware of switch-enum)

Code:

#include <unordered_set>
#include <concepts>

template<typename T>
concept arithmetic = std::integral<T> or std::floating_point<T>;

template<typename T> requires arithmetic<T>
struct Stat
{
    T calculate()
    {
        T sum;    // Not initialized, caused a bug. Compiler gave no error

        for(const T& t : m_set)
        {
            sum += t;
        }
        // Do other calcs
        return sum;
    }

    // Other methods
 
    std::unordered_set<T> m_set;
};
intrigued_66
  • 16,082
  • 51
  • 118
  • 189
  • 2
    I get the error if I use the return value, like `std::cout << s.calculate() << std::endl;`, https://godbolt.org/z/8Pnbcv5Eb – Retired Ninja Dec 04 '22 at 02:40
  • Since `T::calculate` isn't used in this source file, and is not externally visible, gcc doesn'r even bother to compile it. You technically don't have a bug if you invoke undefined behavior in a function that can never be called. – Nate Eldredge Dec 04 '22 at 05:05
  • Note that you generally need to enable optimization (-O and friends) to get uninitialized variable warnings. It won't help until the function can actually be called, though. – Nate Eldredge Dec 04 '22 at 05:06
  • @NateEldredge I couldn't paste the entire code. It's being called from another file. – intrigued_66 Dec 04 '22 at 14:25
  • You can't count on the compiler being able to warn about every bad thing - nor is it required to. Consider warnings as "best effort" - absence of warnings/errors in *no way* implies that the code is correct. Use sanitizers like asan and ubsan to augment your testing - don't rely on warnings alone. – Jesper Juhl Dec 04 '22 at 14:43
  • Compiling with LTO (Link Time Optimization) offers the compiler a broader scope to optimize better and also generate more/better warnings. Consider enabling LTO for your builds. – Jesper Juhl Dec 04 '22 at 14:48

1 Answers1

3

Three things:

  1. GCC's uninitialized variable warnings don't work well unless you enable optimizations (-O, -Og, -O2, -O3, -Os, etc). This is documented (see -Wmaybe-uninitialized): "These warnings are only possible in optimizing compilation, because otherwise GCC does not keep track of the state of variables." See also GCC - no warning about an uninitialized array with -O0

  2. In general, 100% reliable detection of uninitialized variables is impossible (halting problem). So in some sense, be glad when a compiler does warn you, but you really oughtn't to complain too hard if it doesn't, or if it warns about code that is actually fine. Runtime tools such as valgrind are a good supplement (though still won't always catch everything).

  3. The function has to actually be referenced (either used in this source file or visible externally), otherwise the compiler won't actually compile it and in particular won't check for uninitialized variables, not even with optimization enabled. So compiling this source file all by itself will not cause any warnings.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82
  • We don't need 100% reliable detection, it is OK to have some false positives. If the compiler cannot determine whether a variable is initialised, it should warn. AFAICT gcc tries to do just that. Note it says "may be used uninitialized" rather than "is used uninitialized". It doesn't always succeed but probably not because it is the halting problem. – n. m. could be an AI Dec 04 '22 at 06:19
  • I couldn't paste the entire code. It's being called from another file. I also have optimizations enabled. Sorry, they were on another CMake line. I'll add them. – intrigued_66 Dec 04 '22 at 14:26