Domanda

In C++ ci sono un sacco di modi in cui è possibile scrivere codice che compila, ma i rendimenti un comportamento indefinito (Wikipedia).C'è qualcosa di simile in C#?Possiamo scrivere il codice in C# che consente di compilare, ma ha un comportamento indefinito?

È stato utile?

Soluzione

Come altri hanno detto, praticamente nulla nel blocco "non sicuro" può produrre un comportamento definito dall'implementazione; abuso di blocchi non sicuri consente di modificare i byte di codice che compongono il runtime per sé, e quindi tutte le scommesse sono spenti.

Il caso angolo di divisione intera ha un comportamento definito dall'implementazione.

un'eccezione e non la cattura provoca un comportamento definito dall'implementazione - terminare il processo, avviare un debugger, e così via

.

Ci sono una serie di altre situazioni in C # in cui siamo costretti a emettere codice che ha un comportamento implementazione-determinato. Ad esempio, questa situazione:

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

Tuttavia, le situazioni in cui un programma sicuro, ben educati C # ha un comportamento definito dall'implementazione dovrebbero essere abbastanza raro.

Altri suggerimenti

Sì!C'è, anche in un contesto sicuro!(Beh, è l'attuazione definiti per essere definito, almeno)

Ecco una da Marek Safar e VSadov in Roslyn problemi.C'è una mancata corrispondenza tra C# e CLI quanto riguarda bool.

C# crede che ci sia un solo tipo di true, e un tipo di false.

CLI ritiene che false è un byte contenente 0, e tutti gli altri valori sono true.

Questa discrepanza significa che siamo in grado di costringere C# per fare alcuni un (marginalmente) interessante cose cosa:

//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]);

Sopra uscite:

true

true

false

È interessante notare che, il debugger non è d'accordo (deve valutare la verità di diverso?)

enter image description here

Comunque, la conclusione il team di C# sembra essere giunta a è (enfasi aggiunta):

I. E.la lingua sarà rimanere del tutto indifferenti non standard bools.La particolare implementazione (come in MS C# su CIL), riconoscono l'esistenza di non-standard bools e specificare il loro comportamento come undefined

Guardando il Wiki, le situazioni in cui un comportamento indefinito accade sono o non consentito o un'eccezione in C #.

Tuttavia nel codice non sicuro, un comportamento indefinito credo sia possibile, come che consente di utilizzare i puntatori, ecc.

Edit: Sembra che ho ragione: http://msdn.microsoft.com/en-us/library/aa664771%28VS.71%29.aspx

Ha un esempio di comportamento non definito in C #

Secondo il documento ECMA-334 (p 473).

  

Un programma che non contiene alcun   occorrenze del modificatore non sicuri   Non può esibire alcun indefinito   comportamento.

che promuove 'implementazione definita' al caso peggiore, vedere la risposta di Eric Lippert.

Molti e sottoprogrammi hanno esigenze che possono essere riassunti come:

  1. Quando somministrato dati validi, produrre un output valido.

  2. Evitare di lanciare missili nucleari o negando le leggi del tempo e della causalità, anche quando somministrato dati non validi.

Uno dei principali obiettivi di progettazione di Java e linguaggi .NET è che a meno che il codice fa uso di alcuni che sono contrassegnati come "non sicuro", nessuno sforzo particolare è generalmente richiesto per soddisfare il secondo vincolo di cui sopra [anche se alcuni comportamenti legati alla spazzatura raccolta e Finalize possono essere un po 'strano dal punto di vista di tempo / causalità, chi può essere descritto come eccezioni alle normali regole di causalità, piuttosto che una revoca totale di essi]. Tale situazione è molto diversa dalla situazione in C, dove molti tipi di errori dipendenti dai dati (ad esempio integer overflow) possono provocare compilatori si comportano in modo arbitrario compreso making qualunque sarebbero necessarie ipotesi per evitare l'overflow. non esistono i tipi veramente orribile di un comportamento indefinito, che sono incoraggiati in filosofia hypermodern C in C # o altri linguaggi .NET al di fuori di blocchi "non sicuri".

Non proprio, nel senso esattamente Wiki ma suppongo che l'esempio più evidente che mi viene in mente è semplicemente scrivendo un codice threaded, ma poi è come che in qualsiasi lingua.

In generale direi di no.

Utilizza variabile automatica prima di essere inizializzato.

Tutte le variabili devono essere inizializzate. Se si verifica non è un'eccezione.

Divisione per zero

viene generata un'eccezione.

Indicizzare un array fuori limite

viene generata un'eccezione

Come Aequitarum Custode ha sottolineato è possibile utilizzare il codice non sicuro. Poi di nuovo questo non è davvero C #, si è esplicitamente optando fuori l'ambiente C #.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top