4

It's general advice to avoid getting uninitialized members in a class/struct. Consider the following example.

struct Foo
{
    Foo(){}
    int bar;
}

To follow the advice, I have to explicitly initialize bar (e.g. int bar{};).

But what if I always initialize the member by assigning a value to it right after construction (let's forget passing an assigned value as a constructor argument). Should I still follow the above recommendation here? I would still do it if there is no overhead. But, even though negligible, there has to be an associated runtime overhead due to the unused first initialization.

Patrick
  • 73
  • 10
Anubis
  • 6,995
  • 14
  • 56
  • 87
  • 2
    Are you actually worried about the overhead of initializing an `int`? I wouldn't be too concerned. Just initialize it to be safe. – cigien Jul 23 '20 at 17:04
  • 2
    *But what if I always initialize the member by assigning a value to it right after construction* Always is a very strong word. One day you might forget (happens all the time to me) and then you find yourself in UB land, and there be demons. – NathanOliver Jul 23 '20 at 17:06
  • I think `char buffer[BIG_NUMBER];` might be an exception... – Jarod42 Jul 23 '20 at 17:11
  • @Jarod42 Is that because reading from uninitialized `char` is no longer UB? Is that the same exception as for `byte` or is it something else? – cigien Jul 23 '20 at 17:13
  • @cigien I suspect it's because it takes a relatively long time to initialize which isn't nice if you're never going to use it uninitialized. – Ted Lyngmo Jul 23 '20 at 17:16
  • Since you've make a default constructor, you might as well use the member initializer list: `Foo() : bar{} {}` – Ted Lyngmo Jul 23 '20 at 17:17
  • 1
    @TedLyngmo Yes, I think I see your's (and the OP's) point. The trade-off is between cost of initializing, and risk of using without initializing. It's a no-brainer for me personally, but I realize others might have different priorities. – cigien Jul 23 '20 at 17:18
  • It's a `int`. Initializing it takes as close to no time as *doesn't matter* - just do it. – Jesper Juhl Jul 23 '20 at 17:25
  • 1
    Initialize it. Profile, and if profiling says you really need that extra nanosecond... Consider it. But also consider that something somewhere else probably has a much larger impact on performance. – user4581301 Jul 23 '20 at 17:31
  • @NathanOliver I actually do this the other way around: Any member that is not default-initialized needs to be initialized by every constructor. Knowing that (personal) rule helps me remember which members i need to initialize in the constructors (default-initialization might help avoid UB, but it might still leave your object in an inconsistent/illogical state in regards to the logic of your program). – melk Jul 23 '20 at 20:51
  • @cigien: Not for that, but there is generally associated size member to know how many byte are available. (I think of target of `read` or similar functions). – Jarod42 Jul 24 '20 at 10:24

5 Answers5

5

Initializing member variables leads to more stable and predictable class operation; there's no possibility of having the object in an unknown or inconsistent state. On the other hand, certain operations can be relatively slow, and if you know your program logic won't leave the members uninitialized for long you can certainly get away with leaving them. In C, there's no constructor to fill in those members but people have been programming successfully in C since forever.

The cost of initializing an int isn't enough to be worth worrying about 99.9% of the time.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
4

In general, my priority is safety over performance (I've personally suffered more due to weird UB issues than performance issues).

In this particular case, I recommend initializing all your members (especially POD types). Preferably do this inline, since that's the earliest possible place you can do it. This is a pretty easy habit to form, and is easier than making sure that you've initialized all your variables.

Then measure your code. If it turns out that one of your bottlenecks is the initialization of int (or other POD type) members (and I'd be very surprised if this were the case), then yes, take a look at where you're doing unnecessary initializations and remove them.

cigien
  • 57,834
  • 11
  • 73
  • 112
4

Even though so many people consider initializing at the time of definition a good idea, but there's a reason for it being possible in C++.

That reason is exactly the additional redundant assignment. But you only need to worry about it when bar is not just an int and has a much heavier constructor because:

  1. the compiler optimizes away that redundant assignment sometimes.
  2. default initialization usually low cost; but of course that should be checked

So it all comes back to bar being costly to initialize or not.

If it is, I suggest you to not default initialize instead, try to initialize it in your member initializer list if doing so is:

  1. possible, and
  2. doesn't throw errors or you are at least know a way to catch the exceptions

and if that's not a good idea, then I suggest using pointers or references to not initialize at all and use a member function to do so when it's necessary;

and if that's not a good idea either, then I suggest doing the assignment in the constructor of your struct but try to make the default initialization of your bar a not-that-much-costly as possible.

You also need to consider the when you're initializing this object. If your program is a long-running software, then just initialize it at start-up if possible; but of course these situations require more details about the program itself.

I suggest reading the C++ Core Guidelines for more details.

The Moisrex
  • 1,857
  • 1
  • 14
  • 16
0

Firstly You should care about the safety and proper execution of your program. The optimization should be done after profiling and identifying performance bottlenecks.There is a saying that Premature Optimization Is the Root of All Evil

b00rt00s
  • 114
  • 5
0

I can't begin to count the number of times that not initializing something has screwed up the operation of my software. By initializing you also prevent anyone else that uses your class from having the same issue. Also, you do not want to assume that other people are going to practice good coding techniques like you and initialize variables before their use.

Patrick
  • 73
  • 10