Comments (19)
I would like to propose four more operators:
implicit unsafe operator void*(IntPtr);
implicit unsafe operator void*(UIntPtr);
implicit unsafe operator IntPtr(void*);
implicit unsafe operator UIntPtr(void*);
as I am often working with a mixture of P/Invoke-calls (which do not care whether I use void*
or IntPtr
as they are handled identically), CLR-exposed APIs (which use IntPtr
) and pointers.
This would greatly reduce the need of writing (void*)...
or (IntPtr)...
inside my code and would add little effort on the LDT-side, as the implementation of these operators are one-liners.
from csharplang.
Alternative design: #435 dotnet/corefxlab#1471
I think the support for some of the operators on IntPtr
would be valuable even if the other proposal goes through. There are many valid scenarios where I e.g. want to set the lowest bit in a pointer. Having to cast the IntPtr to a "pointer-sized integer" just so that we can set/clear the lowest bit is the same amount of annoyance as having to cast to long
. Sure, it will be more efficient with a "native sized int", but it won't look any better - I want to be able to this as a "pointer operation" as opposed to an "arithmetic operation on an integer type".
from csharplang.
I would suggest adding the following implicit
cast operators , since these do not loose precision.
implicit operator long(System.IntPtr)
implicit operator System.IntPtr(int)
implicit operator ulong(System.UIntPtr)
implicit operator System.UIntPtr(uint)
Not sure I understand the need for the two below. Why are these needed? To support explicit cast?
explicit operator System.IntPtr(System.IntPtr)
explicit operator System.UIntPtr(System.UIntPtr)
from csharplang.
@nietras, comparison of long
/ulong
to IntPtr
/UIntPtr
is explicitly not allowed by the CLI:
As such, comparison operators should not be provided and I would further think that implicit conversion should not be allowed.
from csharplang.
For your consideration I have also done some work on implementing nint/nuint
as thin struct wrappers (written in IL) to expose this API in https://github.com/DotNetCross/NativeInts but getting proper compiler support for all operations would be much better, and it would allow for checked/unchecked
behaviour to be handled correctly. nint
is unchecked by default in my implementation.
from csharplang.
I would also add comparison support for long
and ulong
e.g. IntPtr
can be compared to long
(which it can) and similarly for UIntPtr
and ulong
. There are scenarios where this is interesting, of course you could then cast to e.g. long
before but that seems unnecessary and cumbersome. Any reason to not include these?
from csharplang.
@nietras Concerning your last comment: We will not need to implement comparison operators explicitly, if the implicit-cast-operator from/to (u)long
is implemented.
from csharplang.
not need to implement comparison operators explicitly, if the implicit-cast-operator from/to (u)long is implemented.
@Unknown6656 yes, of course π π
from csharplang.
@tannergooding this table also says you can't compare long
to int
which of course you can π
long l = 1;
int i = 2;
bool b = l > i;
As far as I'm concerned, and I'm no expert, the intent of this table is not to say that you can't compare a native int
with an int64
, you just can't do it directly, so you need to convert first. Just as for int32
. Why? Because, this way you explicitly tell the CLI how the comparison should be done i.e. in i8
with a conv.i8
. So this works fine:
.method public hidebysig specialname static
bool op_GreaterThan(valuetype DotNetCross.NativeInts.nint l,
int64 r) cil managed
{
.maxstack 2
ldarg.0
ldfld native int DotNetCross.NativeInts.nint::Value
conv.i8
ldarg.1
cgt
ret
} // end of method nint::op_GreaterThan
as you can see in https://github.com/DotNetCross/NativeInts/blob/master/src/DotNetCross.NativeInts/NativeInts.il#L781
Whether or not we then wan't implicit or explicit conversions should be based on the same guideline as for int
to/from long
in my view. So do we loose precision? If not, implicit is fine.
I do, however, understand that IntPtr
might be viewed differently due to the historic Ptr
in it's name. But since we would allow arithmetic on IntPtr
, I do not see how converting implicit to long
can be seen as a bad thing. Adding 17 to a pointer to a double
is much worse. π And I would simply ignore the Ptr
part of this, it should have been called nint
, but that is the past.
from csharplang.
I see this has been labelled as "7.2 Candidate" was hoping for 7.1, any way we/I can help speed this up? I see next step is prototype...
from csharplang.
Alternative design: #435 dotnet/corefxlab#1471
from csharplang.
I notice the proposal does not explicitly state that the proposed operators should be "predefined operators" specifically for the C# language. The operators themselves do not need to be defined in metadata. This could be inferred by readers familiar with C# and the underlying IL, but it would still help to clarify it in the proposal. The distinction is particularly important for the compile-time handling of /checked[+ | -]
.
Also, the proposal fails to detail the behavior of checked and unchecked arithmetic with respect to the new operators.
from csharplang.
Yes. The proposal could definitely be more explicit on those points.
I intended these operators to be implemented entirely by the compiler (as is done for the other runtime primitives) and for checked/unchecked handling to be treated the same.
All of this is supported and clearly defined by the CLI spec, its just that the original language design (for whatever reason) decided against including the support for this primitive type (and only this one).
from csharplang.
I intended these operators to be implemented entirely by the compiler (as is done for the other runtime primitives) and for checked/unchecked handling to be treated the same.
How would the compiler know whether the following is an error (due to overflow) or not?
const IntPtr x = (IntPtr)int.MaxValue + (IntPtr)1;
from csharplang.
π @tannergooding If you are happy with my explanation of proposed overflow handling in #435 you could copy it here, and/or modify it as you find appropriate.
from csharplang.
@sharwell Please help me understand how your proposal handles this:
const IntPtr a = unchecked((IntPtr)uint.MaxValue + (IntPtr)1);
const bool c = a == (IntPtr)0;
The bool c
must be true
if run on a 64-bit platform, and false
if run on a 32-bit platform. But since it is a compile-time constant, it must be fixed to one of those values before it is ever run on any platform.
from csharplang.
I posted the answer on the other thread as well. The CLI spec explicitly defines that native int
constants are only allowed to be 32-bit values.
from csharplang.
@tannergooding That does not tell me if unchecked((IntPtr)uint.MaxValue + (IntPtr)1)
is disallowed somehow, or merely not a constant.
from csharplang.
This is an either/or with native int types #435, which we'd rather do. If we drop those, this will be back in consideration.
from csharplang.
Related Issues (20)
- Extension lowering HOT 46
- More user-friendly Compile-time type checking / ζ΄ε δΊΊζ§εηηΌθ―ζΆη±»εζ£ζ₯ HOT 2
- Feature Request: Syntax Sugar for AddRange in List Initialization
- [Proposal]: request support for the ISO 8601 standard 24:00:00 time format in C# HOT 2
- C#: foreach breaking when the IEnumerator.MoveNext method throws exceptions HOT 2
- [Proposal]: Dictionary expressions HOT 94
- strong typed CallerAttributes like CallerMemberName CallerArgumentExpression HOT 2
- CS8509 - Consider Exhaustiveness For Algebraic Data Types HOT 17
- [Proposal]: Implementation specific documentation HOT 2
- [Proposal]: First-Class Span Types HOT 30
- [Proposal]: Collection Expressions Next (C#13 and beyond) HOT 47
- Open issues: Breaking changes HOT 29
- [Proposal]: Field and value as contextual keywords HOT 33
- [Proposal]: Extended identifier syntax
- [API Proposal]: IsNullableAttribute to flow nullability of generic type parameters into methods HOT 4
- Anonymous type optimization HOT 5
- Feature Request: Recursively Foreach
- Compiler can't determine best common type for `switch` expression HOT 8
- [Proposal]: Relax `Add` requirement for collection expression conversions to types implementing `IEnumerable` HOT 2
- [Proposal]: Proposal for Allowing Single-Element Tuples in Type Definitions HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from csharplang.