{"action":"created","issue":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/126","labels_url":"https://api.github.com/repos/dotnet/roslyn/issues/126/labels{/name}","comments_url":"https://api.github.com/repos/dotnet/roslyn/issues/126/comments","events_url":"https://api.github.com/repos/dotnet/roslyn/issues/126/events","html_url":"https://github.com/dotnet/roslyn/issues/126","id":55811484,"number":126,"title":"Proposal: Fixed-size buffers enhancements","user":{"login":"stephentoub","id":2642209,"avatar_url":"https://avatars.githubusercontent.com/u/2642209?v=3","gravatar_id":"","url":"https://api.github.com/users/stephentoub","html_url":"https://github.com/stephentoub","followers_url":"https://api.github.com/users/stephentoub/followers","following_url":"https://api.github.com/users/stephentoub/following{/other_user}","gists_url":"https://api.github.com/users/stephentoub/gists{/gist_id}","starred_url":"https://api.github.com/users/stephentoub/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stephentoub/subscriptions","organizations_url":"https://api.github.com/users/stephentoub/orgs","repos_url":"https://api.github.com/users/stephentoub/repos","events_url":"https://api.github.com/users/stephentoub/events{/privacy}","received_events_url":"https://api.github.com/users/stephentoub/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/dotnet/roslyn/labels/1%20-%20Planning","name":"1 - Planning","color":"cccccc"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Area-Language%20Design","name":"Area-Language Design","color":"5319e7"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Feature%20Request","name":"Feature Request","color":"fc2929"},{"url":"https://api.github.com/repos/dotnet/roslyn/labels/Language-C%23","name":"Language-C#","color":"207de5"}],"state":"open","locked":false,"assignee":{"login":"MadsTorgersen","id":6677272,"avatar_url":"https://avatars.githubusercontent.com/u/6677272?v=3","gravatar_id":"","url":"https://api.github.com/users/MadsTorgersen","html_url":"https://github.com/MadsTorgersen","followers_url":"https://api.github.com/users/MadsTorgersen/followers","following_url":"https://api.github.com/users/MadsTorgersen/following{/other_user}","gists_url":"https://api.github.com/users/MadsTorgersen/gists{/gist_id}","starred_url":"https://api.github.com/users/MadsTorgersen/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MadsTorgersen/subscriptions","organizations_url":"https://api.github.com/users/MadsTorgersen/orgs","repos_url":"https://api.github.com/users/MadsTorgersen/repos","events_url":"https://api.github.com/users/MadsTorgersen/events{/privacy}","received_events_url":"https://api.github.com/users/MadsTorgersen/received_events","type":"User","site_admin":false},"milestone":null,"comments":10,"created_at":"2015-01-28T20:34:25Z","updated_at":"2015-02-11T04:57:42Z","closed_at":null,"body":"## Background\r\nInterop with code implemented with C and C++ often involves fixed-size buffers.  For multiple releases C# has supported the creation of fixed-size arrays on the stack, using the ‘stackalloc’ keyword:\r\n```C#\r\nstatic unsafe void SomeMethod()\r\n{\r\n    int* block = stackalloc int[100];   // array of 100 integers on the stack\r\n    …\r\n}\r\n```\r\nIt’s also supported the creation of fixed-size arrays embedded within structures, using the ‘fixed’ keyword:\r\n```C#\r\ninternal unsafe struct MyBuffer\r\n{\r\n    public fixed char FixedBuffer[128]; // array of 128 chars in the struct\r\n}\r\n```\r\n    \r\n## Problem\r\nIn both of these cases, however, the creation of the fixed-size array may only happen in an unsafe context, hence the usage of the 'unsafe' keyword on the method and struct, respectively, in each of these examples.  Further, in the case of fixed-size buffers in structs, the type can only be of a limited set: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float or double. \r\n\r\nAs C#'s reach is extended and interop becomes even more common-place, it’s desirable to be able to work with fixed-size arrays, in particular embedded in structures, while still getting the benefits of safe code, such as bounds checking.\r\n\r\n## Solution\r\nIf the language supports ref returns (#118), C# can support this without further syntax, with simply relaxing the existing constraints on fixed-size buffers and changing the code generated for these types.  For example, consider the following type:\r\n```C#\r\ninternal struct SYSTEM_POWER_LEVEL\r\n{\r\n    public byte Enable;\r\n    public fixed byte Spare[3]; // inline array, as in C\r\n    public uint BatteryLevel;\r\n    public POWER_ACTION_POLICY PowerPolicy;\r\n    public SYSTEM_POWER_STATE MinSystemState;\r\n}\r\n```\r\nExactly how this is implemented is up to the compiler, but logically the support could be thought of as being implemented as an anonymous struct with a field for every element and an indexer for accessing them:\r\n```C#\r\ninternal struct SYSTEM_POWER_LEVEL\r\n{\r\n    public byte Enable;\r\n    public <>s__ArrayStruct1 Spare;\r\n    public uint BatteryLevel;\r\n    public POWER_ACTION_POLICY PowerPolicy;\r\n    public SYSTEM_POWER_STATE MinSystemState;\r\n}\r\n\r\ninternal struct <>s__ArrayStruct1\r\n{\r\n    public byte Item0, Item1, Item2;\r\n    public ref byte this[int index]\r\n    {\r\n        get {\r\n            switch(index) {\r\n                case 0: return ref Item0;\r\n                case 1: return ref Item1;\r\n                case 2: return ref Item2;\r\n                default: Environment.FailFast();\r\n            }\r\n        }\r\n    }\r\n}\r\n```\r\n\r\nIn the past, developers have resorted to hand-crafting such a solution, implementing helper types like this manually.  Instead, the compiler would be capable of implementing all of that boilerplate for the developer in as efficient a manner as possible.  (If there were concerns around the efficiency of the new code generation, it could potentially only be used when using a type that was previously unsupported or when using a fixed-size buffer in a safe context.  Or alternatively new syntax for expressing this new form could be devised.)"},"comment":{"url":"https://api.github.com/repos/dotnet/roslyn/issues/comments/73834468","html_url":"https://github.com/dotnet/roslyn/issues/126#issuecomment-73834468","issue_url":"https://api.github.com/repos/dotnet/roslyn/issues/126","id":73834468,"user":{"login":"RobertCvn","id":10277532,"avatar_url":"https://avatars.githubusercontent.com/u/10277532?v=3","gravatar_id":"","url":"https://api.github.com/users/RobertCvn","html_url":"https://github.com/RobertCvn","followers_url":"https://api.github.com/users/RobertCvn/followers","following_url":"https://api.github.com/users/RobertCvn/following{/other_user}","gists_url":"https://api.github.com/users/RobertCvn/gists{/gist_id}","starred_url":"https://api.github.com/users/RobertCvn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/RobertCvn/subscriptions","organizations_url":"https://api.github.com/users/RobertCvn/orgs","repos_url":"https://api.github.com/users/RobertCvn/repos","events_url":"https://api.github.com/users/RobertCvn/events{/privacy}","received_events_url":"https://api.github.com/users/RobertCvn/received_events","type":"User","site_admin":false},"created_at":"2015-02-11T04:57:42Z","updated_at":"2015-02-11T04:57:42Z","body":"Will this work in conjuction with MemoryMapped IO to read arrays of structures directly from disk?"}}