Где лучше поместить код инициализации, перед циклом или внутри него?

Извините, если это глупый вопрос :-)

фон

У меня есть устаревший код, который выглядит так:

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, или лучше позвонить один раз перед циклом, и пусть программисты инициализируют то, что им нужно "вручную", если им случится изменить этот код.

edit: к сожалению, myStruct является глобальной переменной, поэтому сделать ее автоматической переменной не является опцией, если я не хочу передать ее в качестве параметра тоннам устаревших функций, которые ее используют.

что я думаю

  • просто вызов initialzationFunction () предотвратит ошибки, если кто-то изменит код и забудет позже инициализировать myStruct.
  • может быть более информативным, чтобы увидеть, какие конкретные поля инициализируются.
  • если только несколько полей будут изменены позже в цикле while, вызов initialzationFunction (), который вводит все поля, является избыточным.

что бы вы сделали?

5 ответов


поскольку поля структуры изменяются внутри цикла while, имеет смысл инициализировать его во время каждой итерации для любой цели обработки, выполняемой в цикле.

Я бы сказал, что нормально повторно инициализировать несколько полей, даже если они не были изменены в цикле. Но отслеживание того, какие поля были изменены, и исключение этих полей при инициализации duing следующая итерация будет хлопот, без которых вы можете обойтись.

альтернативой будет использовать временную переменную strucy со значениями инициализации и просто назначать ее в начале каждой итерации.


Если вы оставляете код для других, чтобы поддерживать, и код не является проверенной точкой доступа, инициализируйте каждый раз, когда будет меньше ошибок, введенных другими.

Если код является проверенной критической точкой доступа, то инициализируйте один раз и очистите код после этого.

преждевременная оптимизация-корень всех зол


ну, в идеале, вы хотели бы сделать минимальное количество операций, которые решают проблему, которую вы решаете. Следуя этой логике, было бы лучше оставить initializationFunction вне цикла и просто обновите поля, необходимые для итерации цикла.

С точки зрения обслуживания, если алгоритм в цикле может сломаться (или вести себя странно), если кто-то забывает сбросить член из своего struct object, тогда было бы лучше инициализировать все на каждом петля. Однако это не устраняет возможность будущих ошибок, это только делает его менее вероятным. В конце концов, все зависит от уровня компетенции сопровождающего.

С точки зрения производительности, это микро-оптимизации, и это действительно не имеет значения (если вы делаете что-то времени в функции инициализации).


Это вопрос баланса и сложности. Если большинство членов в структуре никогда не доступны в цикле while, инициализация, очевидно, излишняя... Но тогда почему они сидят, сгруппировавшись внутри структуры? Какова была их первоначальная цель? В этом случае код сам по себе сложнее, чем необходимо, хотя данные простоя в C, конечно, менее запутан, чем никогда не выполняемый код.

Если OTOH основная часть членов структуры используется в в то время как цикл затем добавляет простое нулевое назначение каждого из них не повредит, потому что каждая последующая операция на этом члене будет смягчать удар по производительности инициализации более или менее 1/n способом.

что я вижу пагубным для обслуживания кода, так это то, что сама функция init должна знать структуру, а это означает, что вы рассеиваете информацию в большем количестве мест, чем необходимо. IIRC C позволяет структурам обнуляться memset (коснитесь структуры как вектора без знака char), и члены выйдут действительно 0 ==> если это вопиюще неправильно, то мне очень жаль, и кто-то может разбить распечатанную версию всех стандартов над моей головой.


если структура должны инициализироваться каждый раз, когда цикл выполняется, а затем делать это внутри нормально. Вы также можете использовать фиктивную структуру, которую вы инициализируете перед циклом, и использовать memcpy для копирования в очищенную структуру в реальную внутри цикла.

или как в принятом ответе на вопрос, связанный со Стивом Джессопом, вместо использования memcpy просто используйте обычное назначение и позвольте компилятору беспокоиться о копировании.