-
-
Notifications
You must be signed in to change notification settings - Fork 111
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
The description of the behaviour of "default" and unsafe arithmetic is unclear, especially the term wrap around #425
Comments
You seem to have an expectation of what should be happening? +~ over the max in your example is undefined behavior. The current description says that the result of an overflow is undefined. That is what you are seeing. +~ isn't performed without overflow, it is undefined what will happen when it overflows. It can vary by platform, including overflowing as you might expect and wrapping around. What your snippet from the docs above doesn't include is: "Undefined in case of" before "Overflow E.g. I32.max_value() +~ I32(1)" so the full statement is: "Undefined in case of Overflow E.g. I32.max_value() +~ I32(1)" |
U32.max_value() + 1 == 0 is a native result for the Intel x64 BUT The unsafe fast operation by tutorial ended without a native result Don't you find it strange? |
As detailed later in that page +? will error on overflow or underflow. Please note nothing in the page says that "+" is safe. It says it is "default arithmetic". |
Please reread what I wrote above before reading below (yes, safe is "default arithmetic" ) Operator | Method | Description
It says here that this operator has a wrapper. That is, this operator is safe in the sense that it has a wrapper. But. Something like this happens That's all (I didn't look in the debugger to see if it looks like this) This is the first contradiction For "+~" This assumes just the native addition operation However, instead we see the result of something like this mov rax, rdx So here we see traces of the wrapper. But there should be no wrappers. This is raw speed! Try it on your version of ponyc, will you have this behavior? |
I see a source of confusion. In the case of "wrap around on over-/underflow"; we will need to clarify that. "wrap" there means literally if you consider the representable range of numbers to be circular, it will wrap around, that is: MAX + 1 = the lowest value representable for the type. It doesn't mean there is some wrapper the current description led you to believe. The description means the opposite of what you are taking it to mean. The intent is to convey that it will wrap on overflow or underflow, not that there is a wrapper. It will do as you put it "a simple underflow". +~ makes no guarantees at all. It is dependent on LLVM functions that declare themselves as undefined behavior in the case of overflow, underflow, etc. Those LLVM functions are the "unsafe" variants that it provides. I can also see how the description of unsafe might have lead to your conclusions. @mfelsche, I think part of the issue here is that the description of unsafe makes it sound like default is doing something different and that isn't necessarily the case. But the presentation suggests that. Really, we want to be contrasting checked/partial with unsafe. But the current reading makes unsafe sound like it is directly contrasted against default and therefore default must be doing something safe. I think we need to rewrite. |
This would be possible if not for the behavior of the operation "+~" The problem is unsafe "+~" it should not contain any wrappers. But "+~" doesn't do it. Instead, it does what I wrote above |
I have the impression that there are two problems here
Since it is obvious that "+~" should give the machine addition command. But does not give (question, only if I have?)
Perhaps it is better to say that the default operations give the same thing on different architectures This is especially true for the "neg" command. Not a wrap around. neg(-128) == -128 for U8 |
So, if you look into the generated IR (obtained from compiling some pony code with
I am not an expert on x86 assembler and i am unable to make sense of the assembler emitted when calling ponyc as I would say that if you think that ponyc is not emitting correct assembler, please investigate further on your machine, look into the generated assembler, and create an issue on the ponyc repo ( https://github.com/ponylang/ponyc/issues ). I am closing this issue as this is not a matter of the tutorial imho. |
I think this is a textbook question too. The words about security compromise are not clear. They're confusing. |
Ok, if we describe this issue as: Please feel free to edit the title accordingly. |
Yes
|
In https://tutorial.ponylang.io/expressions/arithmetic.html
+~ | add_unsafe() | Overflow E.g. I32.max_value() +~ I32(1)
But I see
var x10 = U32.max_value() + 1
env.out.print("U32.max_value() + 1: " + x10.string()) // print 0
x10 = U32.max_value() +~ U32(1)
env.out.print("U32.max_value() +~ 1: " + x10.string()) // 4294967295
That is, "+~" is performed without overflow, but "+" - with overflow
ponyc -v
0.33.2-aff95ec [release]
(windows 7 x64)
The text was updated successfully, but these errors were encountered: