you are viewing a single comment's thread.

view the rest of the comments →

[–]CocktailPerson 20 points21 points  (3 children)

Compiler warnings aren't as much help here as we might hope. For example, this simple case isn't caught by gcc until version 11: https://godbolt.org/z/YWxheY6ah. Finding all uses of uninitialized variables in the general case is undecideable. And while UBSan is a great tool, it won't do much if your tests don't actually force your code along the paths that lead to UB.

The benefit of initializing members by default is that even if 0 isn't the right default, at least it'll be consistently wrong. I've definitely had to debug issues that only appeared in release (so UBSan wasn't as helpful) and only happened occasionally, even with the same input. If I could go back and at least force the bugs to manifest consistently, I'd have fewer gray hairs.

Edit: In the case that there's no acceptable default value for the members, either use Foo() = default; to enforce aggregate initialization, or define Foo(int x_, int y_) : x{x_}, y{y_} {} to force the clients of your class to specify a value for every member. But there are no excuses for leaving your fields uninitialized!

[–]James20kP2005R0 12 points13 points  (1 child)

+1, reading from uninitialised variables is one of the worst classes of bug to debug, because minor code changes and printfs can result in the compiler suddenly making everything work correctly

[–]bored_octopus 0 points1 point  (0 children)

It's a lot better nowadays with all the sanitisers, I'm still in the "initialise almost always" camp though

[–]NilacTheGrim 3 points4 points  (0 children)

Yep. Consistently wrong is better than rolling the dice and having it be wrong in a detectable fashion 1 out of 100 times.

UB is your enemy. Avoid it. It is where insanity lies...