-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
System.IntPtr
and System.UIntPtr
Improvements
#21943
Comments
Ported from https://github.com/dotnet/coreclr/issues/11768. I have an implementation of this proposal here: tannergooding#1. If this is approved, I can submit a PR to dotnet/coreclr directly. |
It might be better to make These are different from e.g. |
I had done it to match the current |
Can Not sure how this can cause compat issues since I have never seen the |
@GSPP, changing the default is likely a breaking change (but I can't say for certain on that). However the existing Additionally, the purpose of this proposal is to expose some interfaces and methods to make |
|
@pentp, for 1, I only included it because those comparisons represent actual IL instructions supported by the runtime. I'm definitely not sold on including them 😄 For 2, I agree it would be useful in some cases (but not when upgrading existing code from |
@joperezr, @AlexGhiondea (since it looks like you are the area owners). Can this be moved to |
that seems reasonable. Marking it as ready-for-review. |
We decided to table this until the |
FYI: The API review discussion was recorded - see https://youtu.be/BEBq3__WfDc?t=245 (10 min duration) |
Watched the API review. There was a lot of discussion around both the There were two sets of APIs included in this proposal:
I think the former should be done regardless, so that The remaining APIs should not be impacted by the
The The The The The |
|
I still think that |
@pentp, I would normally agree. However, there is one key difference which I think makes there be an argument:
So, the argument is that |
But what would that scenario be? Comparing To put it another way: why doesn't |
There is no I'm definitely not convinced they are needed, but they do represent valid IL instructions and valid comparisons for two types which are not implicitly convertible to each other. |
The reduced set of types on the IL evaluation stack has been a very local simplifying assumption to make the IL simpler and more compact. I do not think it makes sense to use it to base the API design on. |
Please mark it api-ready-for-review when it is unblocked and ready. |
Marking this as "ready-for-review" again. This was originally marked as blocked due to belief that it was pending the language team decision (https://youtu.be/HnKmLJcEM74?t=30). However, that should not be the case and |
Having these additional functions, and the rest of the operators exposed on these types would greatly simplify some code in CoreCLR and externally in other libraries that need to deal with raw memory addresses or native sized integers (such as ML.NET). It would also facilitate more code-sharing with CoreFX (CC. @GrabYourPitchforks). |
I agree I don't really see any language blockers here. The only way I could see this being a language issue is if we collectively decided to break compat on |
The APIs at the top are not operators (except for the equal operator). I do not think this proposal would help the code sharing or portability much. If you would like to see what helps with code sharing/portability, replace I think you may want to split this into two different issues: One that is for Parse, Format, etc. And second one for the operators. Each of these is for a very different scenario. |
@jaredpar, @jkotas, @stephentoub. Now that we appear to have stabilized on the plans for the language feature. Do you see any problems with exposing the proposed helpers on |
Makes sense.
I do not think this makes sense. E.g.
Why these two and not other operators? If somebody needs more convenient way to work with
Some parsing/formatting may be ok for convenience, but I am not sure whether we need the whole set proposed above. I see these types as low-level interop types that are never directly displayed in UI, etc. |
👍
I had originally proposed them, but split them off at your request: https://github.com/dotnet/corefx/issues/20256#issuecomment-428766266. However, with
For formatting: from this perspective, it plays into how For parsing: I think not supporting parsing might be understandable, especially since that would encourage people to consider The alternative would be to just tell users wanting to parse/format to use |
CC. @agocke, @MadsTorgersen, @cston It was also raised whether we could expose a property that could be used by the language for making left and right shift deterministic. |
CC. @333fred |
#nullable enable;
namespace System
{
[StructLayout(LayoutKind.Sequential)] // This is implicitly set by the compiler, but should be explicitly declared, as it is done for System.Int32
public partial struct IntPtr : IComparable, IComparable<IntPtr>, IFormattable
{
public static readonly IntPtr MaxValue;
public static readonly IntPtr MinValue;
public static readonly int ShiftMask; // Runtime constant equivalent to (sizeof(nint) * 8) - 1
int IComparable.CompareTo(object value); // Explicitly implemented to ensure that users still get compile-time type checking
public int CompareTo(IntPtr value);
public bool Equals(IntPtr other); // This is currently explicitly implemented as IEquatable<IntPtr>.Equals(IntPtr other)
public string ToString(IFormatProvider? provider);
public string ToString(string format, IFormatProvider? provider);
public static IntPtr Parse(string s);
public static IntPtr Parse(string s, NumberStyles style);
public static IntPtr Parse(string s, IFormatProvider? provider);
public static IntPtr Parse(string s, NumberStyles style, IFormatProvider? provider);
public static bool TryParse(string? s, out IntPtr result);
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out IntPtr result);
}
public partial struct UIntPtr : IComparable, IComparable<UIntPtr>, IFormattable
{
public static readonly UIntPtr MaxValue;
public static readonly UIntPtr MinValue;
public static readonly int ShiftMask; // Runtime constant equivalent to (sizeof(nint) * 8) - 1
int IComparable.CompareTo(object value); // Explicitly implemented to ensure that users still get compile-time type checking
public int CompareTo(UIntPtr value);
public bool Equals(UIntPtr other); // This is currently explicitly implemented as IEquatable<UIntPtr>.Equals(UIntPtr other)
public string ToString(string format); // This is currently exposed on System.IntPtr, but not on System.UIntPtr
public string ToString(IFormatProvider? provider);
public string ToString(string format, IFormatProvider? provider);
public static UIntPtr Parse(string s);
public static UIntPtr Parse(string s, NumberStyles style);
public static UIntPtr Parse(string s, IFormatProvider? provider);
public static UIntPtr Parse(string s, NumberStyles style, IFormatProvider? provider);
public static bool TryParse(string? s, out UIntPtr result);
public static bool TryParse(string? s, NumberStyles style, IFormatProvider? provider, out UIntPtr result);
}
}
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Field |
AttributeTargets.Parameter |
AttributeTargets.Property |
AttributeTargets.ReturnValue |
AttributeTargets.Struct)]
public sealed class NativeIntegerAttribute : Attribute
{
public NativeIntegerAttribute() { }
public NativeIntegerAttribute(byte[] flags) { }
}
} |
@terrajobst, we said that |
For enums, the current proposal is to allow |
If these are properties, the C# implementation for these will "just work" and generate good code predictably. No JIT or VM changes are required. If these are readonly fields, a lot of ceremony is required to predictably generate good code for these, custom built in each runtime, AOT compiler, etc. We can make it work, but it is pain. |
FWIW, we do have a prior art for both styles of runtime constants on IntPtr/UIntPtr:
|
Regarding
The C# compiler will probably emit |
Resolved with #307 |
@tannergooding can you please file a breaking-change doc issue? https://github.com/dotnet/docs/issues/new?template=dotnet-breaking-change.md |
Rationale
The .NET framework provides the
System.IntPtr
andSystem.UIntPtr
types which wrap thenative int
IL primitive (as per ECMA-335).These types are frequently used to represent both handles/pointers and integers whose size depend on the underlying platform.
When being used to represent the latter (platform sized integer) type, users may find a difficult time performing some basic operations, such as comparing two
native ints
to determine sort order.Additionally, with the proposed C#
Native Sized Number Types
(dotnet/csharplang#435) where language support for the primitive operations will be exposed (currently this will be done via partial erasure), the use ofSystem.IntPtr
andSystem.UIntPtr
asnative int
types will become more prevalent (F# is one language that already exposes these operators).As such, these types should be modified to expose a set of APIs that make other common operations easier to perform.
Proposed API
The proposed API here only shows the members that would be new to the types.
System.IntPtr
System.UIntPtr
Other Thoughts
Implementing
System.IConvertible
is done by the other primitive types and may be useful in some cases here as well.It might be worthwhile having
int
implementIComparable<IntPtr>
andIEquatable<IntPtr>
, given that these are valid operations as well.The text was updated successfully, but these errors were encountered: