Pergunta

Em C++ existem um monte de maneiras que você pode escrever um código que compila, mas produz comportamento indefinido (Wikipédia).Existe algo semelhante em C#?Podemos escrever código em C# que compila, mas tem um comportamento indefinido?

Foi útil?

Solução

Como outros mencionaram, praticamente qualquer coisa no bloco "inseguro" pode produzir comportamentos definidos pela implementação; O abuso de blocos inseguros permite alterar os bytes de código que compõem o próprio tempo de execução e, portanto, todas as apostas estão desativadas.

O caso de canto de divisão inteira tem um comportamento definido por implementação.

Jogar uma exceção e nunca capturar isso causa comportamento definido pela implementação-encerrar o processo, iniciar um depurador e assim por diante.

Existem várias outras situações em C#, onde somos forçados a emitir código que tem comportamento determinado por implementação. Por exemplo, esta situação:

http://blogs.msdn.com/ericlippert/archive/2006/04/06/odious-ambiguous-overloads-part-two.aspx

No entanto, as situações em que um programa C# seguro e bem-comportado tem comportamento definido por implementação deve ser bastante raro.

Outras dicas

Sim! Há, mesmo em um contexto seguro! (Bem, é implementação definida para ser indefinida, pelo menos)

Aqui está um de Marek Safar e Vsadov no Problemas de Roslyn. Há uma incompatibilidade entre C# e a CLI em relação a bool.

C# acredita que existe apenas um tipo de true, e um tipo de false.

A CLI acredita nisso false é um byte contendo 0, e todos os outros valores são true.

Esta discrepância significa que podemos coagir C# para fazer algum A (marginalmente) interessante coisas coisa:

//non-standard bool
//We're setting a bool's value to a byte value of 5.
var a = new bool[1];
Buffer.SetByte(a, 0, 5);

//non-standard bool
//We're setting a bool's value to a byte value of 10.
var b = new bool[1];
Buffer.SetByte(b, 0, 10);

//Both are true.
Console.WriteLine(a[0]);
Console.WriteLine(b[0]);

//But they are not the same true.
Console.WriteLine(a[0] == b[0]);

As saídas acima:

true

true

false

Curiosamente, o depurador discorda (deve avaliar a verdade de maneira diferente?)

enter image description here

De qualquer forma, a conclusão que a equipe C# parece ter chegado (ênfase adicionada):

Ou seja, o idioma permanecerá totalmente despreocupado com as bools fora do padrão. A implementação específica (como no MS C# no CIL) reconhecerá a existência de bools fora do padrão e especificará seu comportamento como Indefinido

Olhando para o wiki, as situações em que o comportamento indefinido acontece não são permitidos ou lançam uma exceção em C#.

No entanto, em código inseguro, o comportamento indefinido, acredito ser possível, pois isso permite que você use ponteiros etc.

EDIT: Parece que estou certo: http://msdn.microsoft.com/en-us/library/aa664771%28vs.71%29.aspx

Tem um exemplo de comportamento indefinido em C#

De acordo com o documento ECMA-334 (p. 473):

Um programa que não contém nenhuma ocorrência do modificador inseguro não pode exibir nenhum comportamento indefinido.

Isso promove a 'implementação definida' para o pior caso, consulte a resposta de Eric Lippert.

Muitos e subprogramas têm requisitos que podem ser resumidos como:

  1. Quando receber dados válidos, produza saída válida.

  2. Evite o lançamento de mísseis nucleares ou negar as leis do tempo e da causalidade, mesmo quando recebem informações inválidas.

Um dos principais objetivos de design das línguas Java e .NET é que, a menos que o código use certo que seja marcado como "inseguro", nenhum esforço específico geralmente é necessário para atender à segunda restrição acima [embora alguns comportamentos relacionados à coleta de lixo e Finalize pode ser um pouco estranho desde o ponto de vista do tempo/causalidade, aqueles podem ser descritos como exceções às regras normais de causalidade, em vez de uma revogação total deles]. Essa situação é muito diferente da situação em C, onde muitos tipos de erros dependentes de dados (por exemplo, transbordamento inteiro) podem resultar em compiladores se comportando de maneira arbitrária, incluindo fazer as suposições necessárias para evitar transbordar. Os tipos verdadeiramente horríveis de comportamento indefinido que são incentivados na filosofia h hipermoderna não existem em C# ou em outras línguas .NET fora dos blocos "inseguros".

Não no sentido exatamente do Wiki, mas suponho que o exemplo mais óbvio que me venha é simplesmente escrever algum código roscado, mas é assim em qualquer idioma.

Em geral, eu diria que não.

Utilize a variável antes de ser inicializado.

Todas as variáveis devem ser inicializado.Se não ocorre uma exceção.

Divisão por zero

Exceção é lançada.

A indexação de uma matriz fora dos limites

Exceção é lançada

Como Aequitarum Custos apontado você pode usar o código não seguro.Então, novamente, este não é realmente C#, você está explicitamente optar fora do C# ambiente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top