Quais são os comportamentos indefinidos comuns que um programador de C ++ deve conhecer?
Diga, como:
a[i] = i++;
c++
undefined
undefined-behavior
c++-faq
yesraaj
fonte
fonte
Respostas:
Ponteiro
NULL
ponteiromemcpy
para copiar buffers sobrepostos .Estouros de buffer
Estouros Inteiros
int64_t i = 1; i <<= 72
é indefinido)Tipos, Elenco e Const
int i; i++; cout << i;
)volatile
ousig_atomic_t
ao receber um sinalFunção e Modelo
OOP
Arquivo de origem e pré-processamento
long int
#if
expressãoPara ser classificado
fonte
A ordem em que os parâmetros de função são avaliados é um comportamento não especificado . (Isso não fará o seu programa travar, explodir ou pedir pizza ... diferente do comportamento indefinido .)
O único requisito é que todos os parâmetros sejam totalmente avaliados antes que a função seja chamada.
Este:
Pode ser equivalente a isso:
Ou isto:
Pode ser também; depende do compilador. O resultado pode importar, dependendo dos efeitos colaterais.
fonte
O compilador pode reordenar as partes da avaliação de uma expressão (assumindo que o significado não seja alterado).
Da pergunta original:
Bloqueio verificado duas vezes. E um erro fácil de cometer.
fonte
O meu favorito é "Recursão infinita na instanciação de modelos" porque acredito que é o único onde o comportamento indefinido ocorre no momento da compilação.
fonte
Atribuindo a uma constante após remover o
const
ness usandoconst_cast<>
:fonte
Além do comportamento indefinido , há também o comportamento definido pela implementação igualmente desagradável .
O comportamento indefinido ocorre quando um programa faz algo cujo resultado não é especificado pelo padrão.
O comportamento definido pela implementação é uma ação de um programa cujo resultado não é definido pelo padrão, mas que a implementação é requerida para documentar. Um exemplo é "Literais de caracteres multibyte", da questão Stack Overflow. Existe um compilador C que falha ao compilar isso? .
O comportamento definido pela implementação só o incomoda quando você começa a portar (mas a atualização para a nova versão do compilador também está portando!)
fonte
As variáveis podem ser atualizadas apenas uma vez em uma expressão (tecnicamente uma vez entre os pontos de sequência).
fonte
Uma compreensão básica dos vários limites ambientais. A lista completa está na seção 5.2.4.1 da especificação C. Aqui estão alguns;
Na verdade, fiquei um pouco surpreso com o limite de 1023 rótulos de caso para uma instrução switch, posso prever que sendo excedido o código / lex / parsers gerado com bastante facilidade.
Se esses limites forem excedidos, você terá um comportamento indefinido (falhas, falhas de segurança, etc.).
Certo, eu sei que isso é da especificação C, mas o C ++ compartilha esses suportes básicos.
fonte
Usando
memcpy
para copiar entre regiões de memória sobrepostas. Por exemplo:O comportamento é indefinido de acordo com o Padrão C, incluído no Padrão C ++ 03.
7.21.2.1 A função memcpy
7.21.2.2 A função memmove
fonte
O único tipo para o qual o C ++ garante um tamanho é
char
. E o tamanho é 1. O tamanho de todos os outros tipos depende da plataforma.fonte
Objetos no nível de namespace em unidades de compilação diferentes nunca devem depender um do outro para inicialização, porque sua ordem de inicialização é indefinida.
fonte