Question

En C ++, il y a beaucoup de façons que vous pouvez écrire du code qui compile, mais les rendements comportement non défini (Wikipedia ) . Y at-il quelque chose de similaire en C #? Peut-on écrire du code en C # qui compile, mais a un comportement non défini?

Était-ce utile?

La solution

Comme d'autres l'ont mentionné, à peu près tout dans le bloc « dangereux » peut donner un comportement défini la mise en œuvre; abus de blocs dangereux vous permet de modifier les octets de code qui composent l'exécution elle-même, et donc tous les paris sont ouverts.

Le cas d'angle de la division entière a un comportement défini par l'implémentation.

Lancer une exception et ne jamais attraper provoque un comportement défini par l'implémentation - mettre fin au processus, lancer un débogueur, etc.

.

Il y a un certain nombre d'autres situations en C # où nous sommes obligés d'émettre du code qui a un comportement déterminé la mise en œuvre. Par exemple, cette situation:

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

Cependant, les situations dans lesquelles un programme C sûr, bien comportés # a un comportement défini la mise en œuvre devraient être assez rares.

Autres conseils

Oui! Il y a, même dans un contexte sûr! (Eh bien, il est défini par l'implémentation d'être non défini, au moins)

Voici un de Marek Safar et VSadov dans la problèmes Roslyn IL N'Y un décalage entre C # et CLI en ce qui concerne bool.

C # croit qu'il n'y a qu'un seul type de true, et une sorte de false.

CLI estime que false est un octet contenant 0, et toutes les autres valeurs sont true.

Cet écart signifie que nous pouvons exercer des pressions sur C # pour faire certains a (légèrement) intéressant choses chose:

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

Les sorties ci-dessus:

true

true

false

Fait intéressant, les désapprouve débogueur (doit évaluer différemment la vérité?)

entrer image description ici

Quoi qu'il en soit, la conclusion de l'équipe C # semble venir à se (nous soulignons):

  

i.e.. la langue reste entièrement sans se soucier non standard bools. La mise en œuvre particulière (comme dans MS C # sur CIL) reconnaîtra l'existence de bools et non standard préciser leur comportement comme undefined

En regardant le Wiki, les situations dans lesquelles un comportement non défini se passe-t soit ne sont pas autorisés ou lancer une exception en C #.

Cependant, dans Le code non protégé, un comportement non défini, je crois est possible, qui vous permet d'utiliser des pointeurs etc.

Edit: On dirait que je ne me trompe pas: http://msdn.microsoft.com/en-us/library/aa664771%28VS.71%29.aspx

A un exemple de comportement non défini dans c #

Selon le document ECMA-334 (p 473).

  

Un programme qui ne contient pas de   occurrences du modificateur dangereux   ne peuvent pas présenter de non définie   comportement.

qui favorise la « mise en œuvre défini » au pire des cas, voir la réponse de Eric Lippert.

De nombreux et ont des exigences qui sous-programmes peuvent être résumées comme suit:

  1. Lorsque des données valides donné, produire une sortie valide.

  2. Abstenez de lancer des missiles nucléaires ou infirmant les lois du temps et de la causalité, même lorsque les entrées invalides.

L'un des principaux objectifs de conception de Java et .NET est que si le code utilise certains qui sont marqués comme « dangereux », aucun effort particulier est généralement nécessaire pour répondre à la deuxième contrainte ci-dessus [bien que certains comportements liés aux déchets collecte et Finalize peut être un peu bizarre du temps / point de vue de la causalité, celles-ci peuvent être décrits comme des exceptions aux règles normales de la causalité, plutôt que la révocation totale d'entre eux]. Cette situation est très différente de la situation en C, où de nombreux types d'erreurs dépendant des données (par exemple débordement d'entier) peut entraîner des compilateurs se comportent de façon arbitraire, y compris la prise quel que soit les hypothèses seraient nécessaires pour éviter tout débordement. Les types vraiment horribles de comportement non défini qui sont encouragés dans la philosophie hypermoderne C n'existent pas en C # ou d'autres langages .NET en dehors des blocs « dangereux ».

Pas vraiment dans le sens exactement Wiki mais je suppose que l'exemple le plus évident qui me vient à l'esprit est en train d'écrire simplement un code arborescent, mais il est comme ça dans toutes les langues.

En général, je dirais non.

Utiliser une variable automatique avant d'être initialisé.

Toutes les variables doivent être initialisées. Dans le cas contraire une exception se produit.

Division par zéro

Une exception est levée.

Indexer un tableau hors limites

exception est levée

Aequitarum Custode a souligné que vous pouvez utiliser le code dangereux. Là encore ce n'est pas vraiment C #, vous optez explicitement de l'environnement C #.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top