[Proposal]: [Zero-length fixed buffers] #8834
Replies: 6 comments
-
It might be good to know how often this is a "correctness" thing. That is, how often is Due to these types being "variable length", you can't safely represent them in the type system (even in C/C++) and so therefore doing anything with these types "by value" will lead to incorrect or undesirable behavior. Even in C/C++, such types are effectively required to be created via So you will always need semi-custom logic to account for this and the only real question is whether or not those |
Beta Was this translation helpful? Give feedback.
-
Would the following structure and the Tail array be aligned to a multiple of 64 bits? struct Flex
{
internal IntPtr Head;
internal fixed long Tail[0];
} |
Beta Was this translation helpful? Give feedback.
-
It would follow the default packing for those types on a given platform. Most currently use 8-byte packing for You can always override to a smaller (but not a larger) size using |
Beta Was this translation helpful? Give feedback.
-
I agree. I have encountered similar problems. Since C# supports |
Beta Was this translation helpful? Give feedback.
-
The address calculation with |
Beta Was this translation helpful? Give feedback.
-
Currently, compiling this using System;
unsafe struct Flex
{
internal IntPtr Head;
internal fixed long Tail[3];
} results in:
If the source code had a zero-length fixed buffer If that's not how the metadata would be implemented, then how would the alignment requirement of |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Zero-length fixed buffers
Summary
Allow fixed-buffers to have a length of 0 if the fixed buffer is the final field in a struct of a sequential layout. Currently this code generates
CS1665: Fixed size buffers must have a length greater than zero
.Motivation
This is a common scenario when working with native code (as is one of the most frequent uses of fixed-buffers in general).
It also is useful in some high-performance data stream designs.
For example, in a data stream
The alternative to the above design (using a 1-sized fixed buffer) leads to incorrect
sizeof
values.Could be replaced with
Detailed design
This would legalise having a fixed buffer length of size 0 when the containing type is a struct with sequential layout and the fixed buffer is the final field of the type. If the type was auto layout, or the buffer was not the final field, it would still generate CS1665.
Drawbacks
Niche feature. Can be confusing.
They require very special handling, and can easily break. However, this should be clear via the
unsafe
requirement, and they can't cause easily cause managed heap corruption (which seems to be the requirement forunsafe
code). Implicit compiler copies will cut the struct and remove any excess data, so using these values requires extreme care. However, this is already the case in their uses cases, they just generally use a size of 1 or no field, and manually address, which is arguably more bug-prone.Alternatives
Alternative syntax could be the same as C++ flexible-array members - so it would have no length specifier (but effectively be the same as 0 for all intents and purposes).
Not doing it is not particularly high impact. It is just a relatively low-effort change that helps some native interop scenarios.
Unresolved questions
Should it be allowed in explicit-layout structs?
Design meetings
N/A
Beta Was this translation helpful? Give feedback.
All reactions