Skip to content
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

Un/Checked Expression, and Checked For Loop #461

Open
AdamSpeight2008 opened this issue Jun 28, 2019 · 10 comments
Open

Un/Checked Expression, and Checked For Loop #461

AdamSpeight2008 opened this issue Jun 28, 2019 · 10 comments

Comments

@AdamSpeight2008
Copy link
Contributor

AdamSpeight2008 commented Jun 28, 2019

Related: #180

Checked Expressions

C# has the the concept of check and unchecked expressions, I think we should also bring into VB.net as well. Implicitly assumed to be Checked expression unless explicitly stated Unchecked, as to retain backwards compatibility, We can do this by introducing a new keyword Checked, that acts like a prefix operator on expressions. eg

Dim value As SByte = SByte.MinValue
Dim result As Byte = unchecked( DirectCast( value, Byte) expr`

This is useful when you explicitly want to cast to and from signed to unsigned types, without thrown an exception.


Checked For Loop

A For-Loop is implicitly unchecked (ie it throws exceptions) about being out of range. By prefixing the control variable with Checked eg For Checked index As Sbyte = SByte.MinValue To SByte,MaxValue Step 2. The control variable is checked to remain within the range stated, this has the side-effect of control variable after the final iteration of the loop, not having a value beyond the end value (SByte.MaxValue in the example). This allows the full range of the value types. eg .MinValue To .MaxValue

This can be achieved by altering the lowering of the for loop, in the checked case.

Rough Lowering for Checked For Loop

@Nukepayload2
Copy link

Checked Expressions

If you need to implement unchecked conversions between Byte and SByte without changing the project settings, you can use the following code. It's as fast as the unchecked CByte operator on .NET Core 2.2 x64.

Module SByteAndByteBitConverter
    <StructLayout(LayoutKind.Explicit)>
    Private Structure SByteByteUnion
        <FieldOffset(0)>
        Dim SByteValue As SByte
        <FieldOffset(0)>
        Dim ByteValue As Byte
    End Structure

    <Extension>
    Public Function AsByte(SByteValue As SByte) As Byte
        Return (New SByteByteUnion With {.SByteValue = SByteValue}).ByteValue
    End Function

    <Extension>
    Public Function AsSByte(ByteValue As Byte) As SByte
        Return (New SByteByteUnion With {.ByteValue = ByteValue}).SByteValue
    End Function
End Module

Usage

Dim sb As SByte = -100
Dim ub As Byte = sb.AsByte

@hartmair
Copy link

hartmair commented Jun 28, 2019

This has already been vaguely proposed a long time ago, see #84 and I'd like to highlight the example there that has bothered me a lot of dirty workarounds already: Currently you are not able to implement hashing algorithms, see for example What is the best algorithm for an overridden GetHashCode?

@AdamSpeight2008
Copy link
Contributor Author

Just updating everyone to say there is a prototype implementation at #41104 for this feature.

@paul1956
Copy link

I was working on a NuGet Library but I love if it were built into the compiler. I am playing with BigInteger which would allow conversion from Byte/SByte all the way to ULong/Long but none of it solves the overflow by the compiler itself.

Dim X as byte = CByte(Long.MaxValue + 1)
' Even Unchecked
Dim Y as Byte =CBtype(UnChecked(Long.MaxValue + 1))

@AdamSpeight2008
Copy link
Contributor Author

AdamSpeight2008 commented Jan 22, 2020

@paul1956

Module M
    Sub Main()
        Dim i1 As ULong = ULong.MaxValue
        Dim i2 as ULong= Unchecked( i1 + 1UL)
        System.Console.WriteLine(i2)
    End Sub
End Module

Will output 0 to the console. Changing the expression from 1UL to 1 results in an upcast being performed converting both side to Decimal then a downcast. Unchecked will not change that.

@AdamSpeight2008
Copy link
Contributor Author

@paul1956 My implementation is more of a proof of concept,

  • is possible to add to vb.net.
    Adding to ability to the parser doesn't need a lot of code to implement.
  • semantics match c#
    The BoundExpression already has support for checked / unchecked expressions.

@paul1956
Copy link

@AdamSpeight2008 Based on comment from PR are you going to continue to follow up with this?

@AdamSpeight2008
Copy link
Contributor Author

@paul1956 I'll still work on it, even if it is just for my edification.

@paul1956
Copy link

Why not just follow instruction in PR #41104 and get support assuming your implementation provides the needed functionality you would get lots of user support.

@hartmair
Copy link

Meanwhile, I've created a nuget package for unchecked integer operations in VB.NET, see nuget package VBMath.Unchecked or Github repository System.Runtime.Extensions.Unchecked.

Using System.Numerics

' this will not throw
Dim value = UncheckedInteger.Add(Integer.MaxValue, 1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants