Where is it better to put the initialization code, before the loop or inside it?

StackOverflow https://stackoverflow.com/questions/12367355

  •  01-07-2021
  •  | 
  •  

Domanda

Sorry if this is a silly question :-)

Background

I have legacy code that looks like this:

struct {
int field1;
int field2;
int field3;
int field4;
... many many fields
} myStruct;


while (something) {
initialzationFunction(&myStruct);

// ...change fields of myStruct and do stuff.
}

Each iteration of the while loop needs that myStruct will be initialized to something, lets say zero. initialzationFunction initializes all the fields of myStruct to zero.

The question

Is it good to keep initialzationFunction inside the while loop, or is it better to call it once before the loop, and let the programmers initialize what they need "by hand" if they happen to change this code.

edit: Unfortunately myStruct is a global variable, so making it an automatic variable isn't an option, unless I want to pass it as a parameter to tons of legacy functions that use it.

What I think

  • just calling initialzationFunction() will prevent bugs in case someone modifies the code and forgets to later initialize myStruct.
  • It might be more informative to see what specific fields are initialized.
  • If only a few fields are modified later in the while loop, calling initialzationFunction() that inits all of the fields is redundant.

What would you do?

È stato utile?

Soluzione

Since the struct fields are changed inside the while loop, it makes sense to initialize it during each iteration for whatever the purpose of processing done in the loop.

I would say it's fine to to re-initialize few fields even if there were not modified in the loop. But keeping track of which fields were modified and excluding those fields when initializing duing the next iteration would be a hassle which you can do without.

An alternative would be to use a temporary strucy variable with the initialization values and simply assign it at the start of every iteration.

Altri suggerimenti

If you are leaving the code for others to maintain, and the code is not a proven hotspot, initialize every time as there will be less bugs introduced by others.

If the code is a proven critical hotspot then initialize once and have the code clean up afterwards.

Premature optimisation is the root of all evil

Well, ideally, you would want to do the minimum amount of operations that solve the problem you are tackling. Following this logic, it would be better to leave the initializationFunction out of the loop, and just update the fields you require for a loop iteration.

From the maintenance point of view, if the algorithm in your loop may break (or behave strangely) if someone forgets to reset a member from your struct object, then it would be better to initialize everything at each loop. However, this does not remove the possibility of future bugs, it only makes it less likely. At the end, it all depends on the competence level of the maintainer.

From performance point of view, this is a micro optimization, and it doesn't really matter (unless you do something time consuming in the initialization function).

It is a question of balance and complexity. If most of the members in the struct are never accessed in the while loop, the initialisation is obviously superfluous... BUT THEN why are they sitting grouped together inside a struct then? What was their initial purpose? In this case the code in itself is more complex than necessary although idle data in C is of course less confusing than never-executed code.

If OTOH the major portion of struct members is used in the while loop then adding a mere zero-assignment of each one will not hurt much because every subsequent operation on that member will mitigate the performance hit of the initialisation more or less in an 1/n manner.

What I see detrimental to code maintenance is that the init function itself needs to know the struct, which means that you are dispersing information to more places than necessary. IIRC C allows structs to be nulled by memset (touch the struct as vector of unsigned char) and the members will come out truly 0 ==> if this is blatantly wrong then I am very sorry and someone may smash a printed out version of all standards over my head.

If the structure must be initialized every time the loop runs, then doing it inside is fine. You can also use a dummy structure you initialize before the loop, and use memcpy to copy into the cleared structure into the real one inside the loop.

Or as in the accepted answer to the question linked to by Steve Jessop, instead of using memcpy just use normal assignment and let the compiler worry about the copying.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top