В некоторых случаях, таких как описанный, стандарт C ++ позволяет компиляторам обрабатывать конструкции любым способом, который их клиенты считают наиболее полезным, не требуя, чтобы поведение было предсказуемым. Другими словами, такие конструкции вызывают «неопределенное поведение». Однако это не означает, что такие конструкции должны быть «запрещены», поскольку стандарт C ++ явно отказывается от юрисдикции в отношении того, что «правильно» выполненным программам разрешено делать. Хотя мне неизвестно о каком-либо опубликованном документе Rationale для стандарта C ++, тот факт, что он описывает Undefined Behavior во многом аналогично тому, как это делает C89, предполагает, что предполагаемое значение аналогично: «Неопределенное поведение дает разработчику лицензию, позволяющую не отлавливать определенные программные ошибки, которые являются сложными. для диагностики. Он также определяет области возможного соответствующего расширения языка: разработчик может расширить язык, предоставив определение официально неопределенного поведения ".
Существует множество ситуаций, когда наиболее эффективный способ обработки чего-либо может включать написание частей структуры, которые будут заботиться о нижестоящем коде, в то же время опуская те, которые не будут заботиться о нижестоящем коде. Требование, чтобы программы инициализировали все элементы структуры, включая тех, которые ни о чем не заботятся, без необходимости мешало бы эффективности.
Кроме того, в некоторых ситуациях наиболее эффективным может быть поведение неинициализированных данных в недетерминированность c мода. Например, если:
struct q { unsigned char dat[256]; } x,y;
void test(unsigned char *arr, int n)
{
q temp;
for (int i=0; i<n; i++)
temp.dat[arr[i]] = i;
x=temp;
y=temp;
}
, если нижестоящий код не будет заботиться о значениях каких-либо элементов x.dat
или y.dat
, индексы которых не указаны в arr
, код может быть оптимизировано для:
void test(unsigned char *arr, int n)
{
q temp;
for (int i=0; i<n; i++)
{
int it = arr[i];
x.dat[index] = i;
y.dat[index] = i;
}
}
Это повышение эффективности не было бы возможным, если бы программистам требовалось явно писать каждый элемент temp.dat
, включая те, которые не интересуют нижестоящие, до его копирования.
С другой стороны, в некоторых приложениях важно избежать возможности утечки данных. В таких приложениях может быть полезно иметь версию кода, которая оснащена инструментами для перехвата любой попытки скопировать неинициализированное хранилище, не обращая внимания на то, будет ли на него смотреть нисходящий код, или было бы полезно иметь гарантию реализации, что любое хранилище чье содержимое может быть пропущено, обнуляется или иным образом перезаписывается неконфиденциальными данными.
Из того, что я могу сказать, Стандарт C ++ не пытается сказать, что какое-либо из этих поведений является достаточно более полезным, чем другое, так как чтобы оправдать его обязательство. По иронии судьбы, это отсутствие спецификации может быть направлено на облегчение оптимизации, но если программисты не смогут использовать какие-либо слабые поведенческие гарантии, любая оптимизация будет отменена.