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
proposal: spec: reconsider rule disallowing div-0 by constants #10006
Comments
I think the rule should be that division by zero is invalid in constant expressions, but in non-constant expressions yields a run-time panic if executed. Sorry for not catching this back when the change was made. |
I'm not sure just allowing non-constant divide by zero solves the problem. What about something like: if requiredAlignment != 0 && pageSize % requiredAlignment != 0 { ... } If both pageSize and requiredAlignment are constants, this results in a constant divide-by-zero. Should we barf in that case? I'm not sure. If these constants are really constant, then this code is kind of silly. But probably at least one is a constant dependent on GOARCH or GOOS, in which case it starts to make sense. Maybe we could have a "poison" constant which is generated by a constant divide-by-zero and if that poison constant is ever used, then the compiler fails. |
In your example,
if requiredAlignment != 0 && pageSize % requiredAlignment != 0
the whole condition is a constant expression, we can say that &&, || in
constant expression
are also short-circuit operators, and if a divide by zero (or mod by zero)
needs to be evaluated,
then the that triggers a compiler error, otherwise it is acceptable.
|
That's an interesting suggestion @minux , but it opens other questions: does such a rule apply only to div/mod-0 or also other constant expressions that might fail depending on constant value? For instance: http://play.golang.org/p/NdqsO123u3 Should this be valid? Arguably it should. @randall77 Using a poison constant value amounts to the same effect (and perhaps is easier to explain in the spec), but it needs a definition of what "using" a constant means. I assume it would mean it would be an error to "materialize" such a constant to be used in a runtime-evaluated expression (incl. an assignment or to direct control flow). At least on the type-checker side that would be pretty straight-forward to implement and would work transitively. For instance: const c1 = 1/0 could be valid as long as those constants are not actually used at runtime. And of course using a poisoned constant in another constant expression poisons that one as well. (This is basically the mechanism we had in Sawzall ( http://research.google.com/archive/sawzall.html ), and we called them "undef" values; except there they were actual runtime values. |
The larger context is all constant expressions. Right now |
Consider const n = 1
const d = 0
const x = n / d
func F() {
if false && n/d == 0 {
fmt.Println("??")
}
} If we are going to permit writing |
http://play.golang.org/p/flvr-MFRgR
is a perfectly reasonable program that doesn't compile. Perhaps the spec rule (which admittedly, I advocated) was a mistake after all.
We could reconsider this since permitting it would be backward-compatible.
(See also #10004 for context.)
The text was updated successfully, but these errors were encountered: