52 votes

Code à comportement indéfini en C#

En C++, il y a de nombreuses façons d'écrire du code qui se compile, mais qui rapporte comportement indéfini (Wikipedia) . Existe-t-il quelque chose de similaire en C# ? Peut-on écrire du code en C# qui se compile, mais dont le comportement est indéfini ?

41voto

Eric Lippert Points 300275

Comme d'autres l'ont mentionné, à peu près tout ce qui se trouve dans le bloc "unsafe" peut donner lieu à un comportement défini par l'implémentation ; l'abus des blocs "unsafe" vous permet de modifier les octets de code qui constituent le runtime lui-même, et donc tous les paris sont ouverts.

La division int.MinValue/-1 a un comportement défini par l'implémentation.

Lancer une exception et ne jamais l'attraper entraîne un comportement défini par l'implémentation -- terminer le processus, lancer un débogueur, etc.

Il existe un certain nombre d'autres situations en C# où nous sommes obligés d'émettre du code dont le comportement est déterminé par l'implémentation. 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 et bien conçu a un comportement défini par l'implémentation devraient être assez rares.

0 votes

Ouch, ce problème de surcharge est vraiment bizarre. Et moi qui pensais que DivisionByZeroException était le comportement attendu sur 1/0 . Quoi qu'il en soit, j'ajouterai demain...

1 votes

Qui a parlé de division par zéro ?

5 votes

@Eric : Je pensais que le coin que vous avez mentionné était le 1/0 habituel. J'ai fait des recherches et j'ai trouvé que c'est en fait int.MinValue/-1 .

12voto

Brett Allen Points 1989

En regardant le Article de Wikipedia sur le comportement indéfini En C#, les situations dans lesquelles un comportement indéfini se produit sont soit interdites, soit assorties d'une exception.

Cependant, dans un code non sécurisé, un comportement indéfini est possible, car il permet d'utiliser des pointeurs, etc.

Edit : On dirait que j'ai raison : http://msdn.microsoft.com/en-us/library/aa664771%28VS.71%29.aspx

A un exemple de comportement indéfini en c#

6 votes

Quand vous dites "le Wiki", à quel Wiki faites-vous référence ?

1 votes

@Jeff Yates : Le lien "comportement indéfini" dans la question renvoie à Wikipedia.

0 votes

@Jeff Yates : Oui, je regardais son lien wikipedia pour déterminer quelles situations provoquent des comportements indéfinis.

11voto

Henk Holterman Points 153608

Selon le document ECMA-334 (p. 473) :

Un programme qui ne contient aucune d'occurrences du modificateur unsafe ne peut pas présenter de comportement comportement non défini.

Cela fait de la "mise en œuvre définie" le pire des cas, voir la réponse d'Eric Lippert.

0 votes

Unspecified, plutôt que Implementation-Defined, du moins tel que le terme est utilisé dans la spécification C. Si la spécification considère une implémentation comme étant définie par l'implémentation, alors les implémentations conformes doivent fournir une documentation suffisante pour permettre au programmeur de savoir exactement comment elle se comportera. Une implémentation pourrait légitimement spécifier que (signed char)128 donnerait -126 pendant la première moitié de chaque phase de la lune, et -127 pendant la seconde moitié, mais seulement si l'implémentation détermine réellement la phase de la lune. Les implémentations ne peuvent pas simplement dire "donne une valeur arbitraire".

0voto

mfloryan Points 5544

Pas vraiment dans le sens exact de Wiki, mais je suppose que l'exemple le plus évident qui me vient à l'esprit est simplement d'écrire du code threadé, mais c'est comme ça dans n'importe quel langage.

3 votes

C'est juste non déterministe, pas indéfini. Vous avez toujours la garantie de savoir exactement ce que chaque thread va faire. Vous ne connaissez simplement pas l'ordre exact dans lequel les choses se produisent, et vous pouvez donc obtenir des résultats surprenants.

2 votes

@mfloryan : malheureusement, lorsque vous créez un nouveau fil de discussion en C#, vous ne pouvez pas vous attendre à ce qu'une partie de NetHack soit lancée. Ah, le bon vieux temps où l'on pouvait y jouer en exécutant gcc...

-2voto

Chuck Conway Points 10293

En général, je dirais non.

Utiliser une variable automatique avant qu'elle ne soit initialisée.

Toutes les variables doivent être initialisées. Si ce n'est pas le cas, une exception se produit.

Division par zéro

Une exception est levée.

Indexation d'un tableau hors limites

Une exception est levée

Comme l'a souligné Aequitarum Custos, vous pouvez utiliser du code non sécurisé. Mais encore une fois, ce n'est pas vraiment du C#, vous choisissez explicitement de sortir de l'environnement C#.

3 votes

Code non sécurisé est C#. Ce à quoi vous renoncez, ce sont les garanties du code géré.

0 votes

C'est pas C# unsafe { int* px1 ; int* px2 = &i ; F(out px1, ref px2) ; Console.WriteLine("*px1 = {0}, *px2 = {1}", *px1, *px2) ; // comportement indéfini } Oui, c'est écrit en C#.

7 votes

Bien sûr, c'est du C# parfaitement légal. Une implémentation de C# qui implémente le sous-ensemble optionnel "unsafe" est toujours une implémentation de C#.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X