Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>What is a fixed buffer?</h2> <p>From MSDN:</p> <blockquote> <p>In C#, you can use the fixed statement to create a buffer with a fixed size array in a data structure. This is useful when you are working with existing code, such as code written in other languages, pre-existing DLLs or COM projects. The fixed array can take any attributes or modifiers that are allowed for regular struct members. The only restriction is that the array type must be <strong>bool, byte, char, short, int, long, sbyte, ushort, uint, ulong, float, or double</strong>.</p> </blockquote> <p>I'm just going to quote Mr. Hans Passant in regards to why a fixed buffer <strong>MUST</strong> be <code>unsafe</code>. You might see <a href="https://stackoverflow.com/questions/2881422/why-is-a-fixed-size-buffers-arrays-must-be-unsafe">Why is a fixed size buffers (arrays) must be unsafe?</a> for more information.</p> <blockquote> <p>Because a "fixed buffer" is not a real array. It is a custom value type, about the only way to generate one in the C# language that I know. There is no way for the CLR to verify that indexing of the array is done in a safe way. The code is not verifiable either. The most graphic demonstration of this:</p> </blockquote> <pre><code>using System; class Program { static unsafe void Main(string[] args) { var buf = new Buffer72(); Console.WriteLine(buf.bs[8]); Console.ReadLine(); } } public struct Buffer72 { public unsafe fixed byte bs[7]; } </code></pre> <blockquote> <p>You can arbitrarily access the stack frame in this example. The standard buffer overflow injection technique would be available to malicious code to patch the function return address and force your code to jump to an arbitrary location.</p> <p>Yes, that's quite unsafe.</p> </blockquote> <h2>Why can't a fixed buffer contain non-primitive data types?</h2> <p>Simon White raised a valid point:</p> <blockquote> <p>I'm gonna go with "added complexities to the compiler". The compiler would have to check that no .NET specific functionality was applied to the struct that applied to enumerable items. For example, generics, interface implementation, even deeper properties of non-primitive arrays, etc. No doubt the runtime would also have some interop issues with that sort of thing too.</p> </blockquote> <p>And Ibasa:</p> <blockquote> <p>"But that is already done by the compiler." Only partly. The compiler can do the checks to see if a type is managed but that doesn't take care of generating code to read/write structs to fixed buffers. It can be done (there's nothing stopping it at CIL level) it just isn't implemented in C#.</p> </blockquote> <p>Lastly, Mehrdad:</p> <blockquote> <p>I think it's literally because they don't want you to use fixed-size buffers (because they want you to use managed code). Making it too easy to interop with native code makes you less likely to use .NET for everything, and they want to promote managed code as much as possible.</p> </blockquote> <p><strong>The answer</strong> appears to be a resounding "it's just not implemented". </p> <h2>Why's it not implemented?</h2> <p>My <em>guess</em> is that the cost and implementation time just isn't worth it to them. The developers would rather promote managed code over unmanaged code. It could possibly be done in a future version of C#, but the current CLR lacks a lot of the complexity needed.</p> <p>An alternative could be the security issue. Being that fixed buffers are immensely vulnerable to all sorts of problems and security risks should they be implemented poorly in your code, I can see why the use of them would be discouraged over managed code in C#. Why put a lot of work into something you'd like to discourage the use of?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload