Где лучше поместить код инициализации, перед циклом или внутри него?
Извините, если это глупый вопрос :-)
фон
У меня есть устаревший код, который выглядит так:
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
просто используйте обычное назначение и позвольте компилятору беспокоиться о копировании.