On Tue, Nov 27, 2007 at 05:25:22PM +0300, Damir Shayhutdinov wrote: > > Этот кусок кода можно упростить до > > > > extern struct { char a; } from[1], to[1]; > > void copy(int n) > > { > > if (n != 0) > > memcpy(&to[1], &from[0], sizeof(to[1])); > > } > > > > Компилятор однозначно говорит: will always overflow destination buffer > > Он прав, если случится n != 0, то будет выполнен код, который всегда > > приводит к overflow. Если n всегда 0, то этот вредоносный код не > > выполнится никогда, и его можно убрать вместе с проверкой n != 0. > > > > В вашем случае предупреждение компилятора пропадёт, как только MAX_PLAYERS > > станет больше 1. > Да, но проблема в том что это символ препроцессора, и насколько я > понимаю, авторы в будущем поменяют его значение. Сам по себе код > вполне правомочен, если бы компилятор не знал, что MAX_PLAYERS = 1. > Авторы писали код так, чтобы он не зависел от значения MAX_PLAYERS. > > А в итоге получается что компилятор из-за оптимизации запаниковал на > ровном месте. Формально он конечно прав, а практически - нет. Это я и > считаю несовершенством проверки. Он и практически прав: поскольку у функции CopyMeToNetworkMe() глобальная линковка, нет никаких гарантий того что она будет вызвана правильно. > Из-за него к каждому предупреждению компилятора приходится подходить > индивидуально. Обидно также то, что апстриму необходимость guard-а > будет сложно объяснить. Моё объяснение может оказаться недостаточно доступно? > > Добавенная вами проверка -- это не лишний guard, благодаря ней > > компилятор выкинул весь цикл. > > Ну да, если основываться на предположении что MAX_PLAYERS будет всегда равно 1. Альтернативный вариант -- завернуть этот злополучный цикл в #if MAX_PLAYERS > 1. -- ldv