Em alguns casos, como o descrito, o Padrão C ++ permite que os compiladores processem construções da maneira que seus clientes acharem mais útil, sem exigir que o comportamento seja previsível. Em outras palavras, essas construções invocam "comportamento indefinido". Isso não implica, no entanto, que tais construções sejam "proibidas", uma vez que o Padrão C ++ renuncia explicitamente à jurisdição sobre o que programas bem formados são "permitidos". Embora eu não conheça nenhum documento publicado do Rationale para o C ++ Standard, o fato de descrever o Comportamento indefinido da mesma forma que o C89 sugere o significado pretendido é semelhante: "O comportamento indefinido dá ao implementador licença para não detectar certos erros de programa difíceis. diagnosticar.
Existem muitas situações em que a maneira mais eficiente de processar algo envolveria escrever as partes de uma estrutura com a qual o código downstream se importaria, enquanto omitir aquelas que o código downstream não se importaria. Exigir que os programas inicializem todos os membros de uma estrutura, incluindo aqueles com os quais nada se importa, impediria desnecessariamente a eficiência.
Além disso, há algumas situações em que pode ser mais eficiente que dados não inicializados se comportem de maneira não determinística. Por exemplo, dado:
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;
}
se o código downstream não se importar com os valores de quaisquer elementos x.dat
ou y.dat
cujos índices não foram listados arr
, o código poderá ser otimizado para:
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;
}
}
Essa melhoria na eficiência não seria possível se os programadores precisassem escrever explicitamente todos os elementos do temp.dat
, incluindo aqueles que não se importam com o downstream, antes de copiá-lo.
Por outro lado, existem algumas aplicações em que é importante evitar a possibilidade de vazamento de dados. Nesses aplicativos, pode ser útil ter uma versão do código instrumentada para interceptar qualquer tentativa de copiar o armazenamento não inicializado, sem levar em consideração se o código downstream o analisaria, ou pode ser útil ter uma garantia de implementação que qualquer armazenamento cujo conteúdo pudesse ser vazado seria zerado ou substituído por dados não confidenciais.
Pelo que posso dizer, o Padrão C ++ não tenta dizer que qualquer um desses comportamentos é suficientemente mais útil que o outro para justificar sua exigência. Ironicamente, essa falta de especificação pode ter como objetivo facilitar a otimização, mas se os programadores não puderem explorar nenhum tipo de garantia comportamental fraca, qualquer otimização será negada.