8

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

背景

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

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() 是多余的。

你会怎么做?

4

5 回答 5

6

如果您将代码留给他人维护,并且代码不是经过验证的热点,请每次初始化,因为他人引入的错误会更少。

如果代码是经过验证的关键热点,则初始化一次,然后清理代码。

过早的优化是万恶之源

于 2012-09-11T10:18:14.760 回答
5

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

我想说即使循环中没有修改,也可以重新初始化几个字段。但是,在下一次迭代期间进行初始化时,跟踪哪些字段被修改并排除这些字段将是一件您可以不用的麻烦。

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

于 2012-09-11T10:26:40.650 回答
1

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

或者就像史蒂夫·杰索普(Steve Jessop)所链接的问题的公认答案一样,而不是memcpy仅使用普通赋值并让编译器担心复制。

于 2012-09-11T10:24:07.860 回答
1

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

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

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

于 2012-09-11T10:52:25.157 回答
1

好吧,理想情况下,您希望执行最少的操作来解决您正在解决的问题。按照这个逻辑,最好离开initializationFunction循环,只更新循环迭代所需的字段。

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

从性能的角度来看,这是一个微优化,并没有什么关系(除非你在初始化函数中做了一些耗时的事情)。

于 2012-09-11T10:29:56.577 回答