Já vi os termos "IB" e "UB" usados várias vezes, principalmente no contexto de C ++. Eu tentei pesquisá-los, mas aparentemente essas combinações de duas letras são muito úteis. : P
Então, eu pergunto a você ... o que eles querem dizer, quando são ditos como se fossem uma coisa ruim?
c++
terminology
definition
cHao
fonte
fonte
Respostas:
IB: Comportamento definido pela implementação. O padrão deixa para o compilador / plataforma particular definir o comportamento preciso, mas requer que seja definido.
Usar o comportamento definido pela implementação pode ser útil, mas torna seu código menos portátil.
UB: Comportamento indefinido. O padrão não especifica como um programa que invoca um comportamento indefinido deve se comportar. Também conhecido como "demônios nasais" porque, teoricamente, poderia fazer os demônios saírem do seu nariz.
Usar um comportamento indefinido quase sempre é uma má ideia. Mesmo que pareça funcionar às vezes, qualquer mudança no ambiente, compilador ou plataforma pode quebrar seu código aleatoriamente.
fonte
Comportamento definido pela implementação e comportamento indefinido
O padrão C ++ é muito específico sobre os efeitos de várias construções e, em particular, você deve estar sempre ciente destas categorias de problemas :
Comportamento indefinido significa que não há absolutamente nenhuma garantia dada. O código pode funcionar, ou pode atear fogo ao seu disco rígido ou fazer demônios voarem pelo seu nariz . No que diz respeito à linguagem C ++, absolutamente tudo pode acontecer. Em termos práticos, isso geralmente significa que você tem um bug irrecuperável. Se isso acontecer, você não pode realmente confiar em nada sobre seu aplicativo (porque um dos efeitos desse comportamento indefinido pode ter sido apenas bagunçar a memória usada pelo resto do seu aplicativo). Não é necessário que seja consistente, portanto, executar o programa duas vezes pode gerar resultados diferentes. Pode depender das fases da lua, da cor da camisa que você está vestindo ou de qualquer outra coisa.
Comportamento não especificado significa que o programa deve fazer algo lógico e consistente, mas não é necessário documentar isso.
O comportamento definido pela implementação é semelhante ao não especificado, mas também deve ser documentado pelos escritores do compilador. Um exemplo disso é o resultado de a
reinterpret_cast
. normalmente , ele simplesmente muda o tipo de um ponteiro, sem modificar o endereço, mas o mapeamento é realmente definido pela implementação, então um compilador poderia mapear para um endereço completamente diferente, desde que documentasse essa escolha. Outro exemplo é o tamanho de um int. O padrão C ++ não se importa se tem 2, 4 ou 8 bytes, mas deve ser documentado pelo compiladorMas o comum para todos esses é que é melhor evitá-los. Quando possível, mantenha o comportamento 100% especificado pelo próprio padrão C ++. Dessa forma, você tem portabilidade garantida.
Freqüentemente, você também precisa confiar em algum comportamento definido pela implementação. Pode ser inevitável, mas você ainda deve prestar atenção a isso e estar ciente de que está contando com algo que pode mudar entre diferentes compiladores.
O comportamento indefinido, por outro lado, deve sempre ser evitado. Em geral, você deve apenas assumir que isso faz seu programa explodir de uma forma ou de outra.
fonte
IB: é o comportamento definido pela implementação - o compilador deve documentar o que ele faz. Executar uma
>>
operação em um valor negativo é um exemplo.UB: comportamento indefinido - o compilador pode fazer o que quiser, incluindo simplesmente travar ou fornecer resultados imprevisíveis. Desreferenciar um ponteiro nulo se enquadra nesta categoria, mas também em coisas mais sutis, como aritmética de ponteiro, que está fora dos limites de um objeto de matriz.
Outro termo relacionado é 'comportamento não especificado'. Isso é algo entre comportamentos definidos e indefinidos pela implementação. para comportamento não especificado, o compilador deve fazer algo de acordo com o padrão, mas exatamente quais escolhas o padrão fornece depende do compilador e não precisa ser definido (ou mesmo consistente). Coisas como a ordem de avaliação das subexpressões se enquadram nesta categoria. O compilador pode executá-los em qualquer ordem que desejar e pode fazê-lo de maneira diferente em compilações diferentes ou mesmo em execuções diferentes da mesma compilação (improvável, mas permitido).
fonte
A versão curta:
Comportamento definido pela implementação (IB): programado corretamente, mas indeterminado *
Comportamento indefinido (UB): programado incorretamente (ou seja, um bug !)
*) "indeterminado" no que diz respeito ao padrão de linguagem, é claro que será determinado em qualquer plataforma fixa.
fonte
UB: Comportamento Indefinido
IB: Comportamento Definido pela Implementação
fonte