在循环之前或内部放置初始化代码更好?

时间:2012-09-11 10:07:49

标签: c legacy-code

对不起,如果这是一个愚蠢的问题: - )

背景

我有遗留代码,如下所示:

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


while (something) {
initialzationFunction(&myStruct);

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

while循环的每次迭代都需要将myStruct初始化为某个东西,假设为零。 initialzationFunction将myStruct的所有字段初始化为零。

问题

将initialzationFunction保留在while循环中是否合适, 或者最好在循环之前调用一次,如果碰巧改变了这段代码,让程序员“手动”初始化他们需要的东西。

编辑:不幸的是myStruct是一个全局变量,因此将其作为自动变量不是一个选项,除非我想将它作为参数传递给大量使用它的遗留函数。

我的想法

  • 只需调用initialzationFunction()就可以防止有人修改代码并忘记稍后初始化myStruct的错误。
  • 查看哪些特定字段已初始化可能会提供更多信息。
  • 如果稍后在while循环中只修改了几个字段,则调用所有字段中的initialzationFunction()是多余的。

你会做什么?

5 个答案:

答案 0 :(得分:6)

如果您要保留代码以供其他人维护,并且代码不是经过验证的热点,则每次都会初始化,因为其他人会引入较少的错误。

如果代码是经过验证的关键热点,那么初始化一次并在之后清理代码。

过早优化是万恶之源

答案 1 :(得分:5)

由于struct字段在while循环中被更改,因此在每次迭代期间初始化它是有意义的,无论循环中处理的目的是什么。

我会说,即使在循环中没有修改,重新初始化几个字段也没关系。但是要跟踪修改哪些字段并排除这些字段 当初始化duing时,下一次迭代将是一个麻烦,你可以做到没有。

另一种方法是使用带有初始化值的临时字符串变量,并在每次迭代开始时简单地分配它。

答案 2 :(得分:1)

如果每次循环运行时都必须初始化结构,那么在内部进行就可以了。您还可以使用在循环之前初始化的虚拟结构,并使用memcpy将已清除的结构复制到循环内的实际结构中。

或者在Steve Jessop链接的问题的接受答案中,不是使用memcpy而是使用正常分配,让编译器担心复制。

答案 3 :(得分:1)

嗯,理想情况下,您可能希望执行最少量的操作来解决您正在解决的问题。遵循这个逻辑,最好将initializationFunction放在循环之外,只需更新循环迭代所需的字段。

从维护的角度来看,如果某人忘记重置struct对象中的成员,循环中的算法可能会中断(或行为异常),那么最好在每个循环中初始化所有内容。但是,这并没有消除未来错误的可能性,只会降低它的可能性。最后,这一切都取决于维护者的能力水平。

从性能的角度来看,这是一个micro optimization,它并不重要(除非你在初始化函数中做了一些时间)。

答案 4 :(得分:1)

这是一个平衡和复杂的问题。如果结构中的大多数成员永远不会在while循环中被访问,那么初始化显然是多余的......但是为什么它们在一个结构中坐在一起呢?他们最初的目的是什么?在这种情况下,代码本身比必要的更复杂,尽管C中的空闲数据当然比从未执行过的代码更容易混淆。

如果在while循环中使用了结构成员的主要部分的OTOH,那么添加每个结构的零分配将不会造成太大的影响,因为该成员的每个后续操作都会或多或少地降低初始化的性能。 1 / n方式。

我认为对代码维护有害的是init函数本身需要知道结构,这意味着您将信息分散到不必要的地方。 IIRC C允许结构体被memset清零(将结构作为无符号字符的向量触摸),成员将真正出现0 ==>如果这是明显的错误,那么我很抱歉,有人可能会打破我头上所有标准的印刷版本。