[Proposal] Allow explicit field endianness #8249
Replies: 6 comments 12 replies
-
Also we can expand custom types with such interface: interface ISupportsEndianness<T> {
T AsLittleEndian { get; set; }
T AsBigEndian { get; set; }
} It should be especially applicable to bend Guid uuid = Guid.NewGuid();
return uuid.ToString(); Is translated to Guid uuid;
uuid.ValueAsBigEndian = Guid.NewGuid();
return uuid.ValueAsBigEndian.ToString(); |
Beta Was this translation helpful? Give feedback.
-
This, IMO, is a really interesting idea. But it’s so niche I can’t see the LDM entertaining it. The vast majority of the time you’re doing interop, everything is in native endianness. Only when serializing to the wire does endianness tend to matter, and that can already be accomplished through a custom marshaller. Obligatory, “source generators can help here” sentence. |
Beta Was this translation helpful? Give feedback.
-
This reads much more like a runtime proposal than a C# proposal since the suggestion is to modify the IL opcodes necessary to read/write these fields. IMO, baking this into the runtime+language isn't necessary, you could accomplish this just as easily by defining properties where the accessor methods handle the translation. |
Beta Was this translation helpful? Give feedback.
-
But this sounds like a major issue for a very niche problem. There is probably already a small percentage of C# programmers who know what the endianness is and even a smaller amount who need different endianess support by the compiler itself. |
Beta Was this translation helpful? Give feedback.
-
I suspect there's no use case for accessing a managed datum that needs to worry about endianess. The only use case I see is where code needs to access unmanaged memory using a different endianness to the current environment, and it might be useful to then be able to declare a pointer to have a specific endianess. |
Beta Was this translation helpful? Give feedback.
-
We can make C# much better for interop with binary formats by specifying exact endianness of the field like such:
Binary formats always require us to use strict endianess to operate with fields, thus it would be very nice to have such attribute to specify that field is supposed to be strictly in such endianness. This should work exactly same as
volatile
keyword, i.e. all read/write operations with such field should emit a new opcode likeOpCodes.LEnd
orOpCodes.BEnd
. For the backwards compatibility we can just compile old languages with explicit batches of opcodes to perform such operations.Example
New .Net
There is just IL code. JIT will just emit corresponding machine code inline without any need for custom methods.
netstandard2.1
.Net prior netstandard2.1.
Of course, it looks bulk and heavy, but I think there is definitely a way to implement it much better. Not as good as for new .Net, but still much better than the way I wrote it. For example, compiler will look for a public/internal class with fixed name like
BinaryPrimitives
that may be either internally implemented or attached as nuget package. Then compiler will just take corresponding public staticRead/Write()
method from this class and use it. It already works same way forinit
,required
and other attributes on older frameworks.Conversions
For the questions about conversions between
ref lend
,ref bend
andref
- we should allow such conversions, they just have to be explicit. For example,ref lend T Unsafe.AsRefLittleEndian(ref T x)
. Meanwhile value conversion should be implicit since this keyword doesn't affect value in any way, it affects only read/write operations.Operations
This endianness proposal involves only READ/WRITE operations, i.e. only process of reading or storing value from memory. It SHOULD NOT affect any other operation, like <<. >>, ^, & and etc. All of them are performed on READ values, i.e. AFTER conversion from our specified endianness to system native conversion. Thus all those operations work as is, lend/bend modifiers are not applicable to them.
Beta Was this translation helpful? Give feedback.
All reactions