The loop var change *does* break compatibility. And it did so knowingly and
- as clearly explained - was an exception.
Stop arguing in bad faith.

On Thu, Feb 29, 2024 at 7:03 AM tapi...@gmail.com <tapir....@gmail.com>
wrote:

>
>
> On Wednesday, February 28, 2024 at 3:19:37 PM UTC+8 Axel Wagner wrote:
>
> That would break backwards compatibility, though. And it would be a
> re-definition (i.e. existing code would compile, but behave differently at
> runtime) and is hence not allowed even under the Go 2 transition rules.
>
>
> With Go version specified, nothing can be broken. For example, the loop
> var change in Go 1.22 doesn't break backwards compatibility. (Though this
> is not my opinion, ;D)
>
>
> I'm also not sure you can exclude *all* pointers to zero-sized variables.
> Note that `[0]T` is also zero-sized and you can convert slices (even empty
> ones) into array-pointers. And you can take the address of struct fields.
>
> All of this to solve an honestly pretty small issue. It's a corner, yes.
> But it isn't a particularly sharp corner.
>
> On Wed, Feb 28, 2024 at 8:06 AM 'Brian Candler' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
> > let's consider the two possible definitions:
> >
> > 1. Pointers to distinct zero-size variables are equal: [...]
> > 2. Pointers to distinct zero-size variables are not equal:
>
> Another possibility:
>
> 3. Equality comparisons between pointers to zero-size variables are
> forbidden at compile time.
> 3a. If you wrap two such values in interfaces and try to compare them,
> then you get a runtime panic, same as certain cases today
> <https://go.dev/play/p/MgtUz2em65A>.
>
> Indeed, what if it were forbidden to take a pointer to a zero-sized
> variable in the first place? There is nothing to point at, after all.
>
> On Wednesday 28 February 2024 at 07:17:24 UTC+7 Brien Colwell wrote:
>
> I think the surprising part is that the comparison result can change for
> the same values because of the assumption that pointers never change. This
> is implied by the spec but easy to miss.
>
> "Pointers to distinct zero-size variables may or may not be equal."
> "Pointers to distinct zero-size variables may or may not be equal and the
> results may or may not be repeatable in any context."
>
> Agree once a programmer is aware of the behavior it can be avoided.
>
> Best,
> Brien
>
>
> On Feb 27, 2024, at 3:06 PM, 'Axel Wagner' via golang-nuts <
> golan...@googlegroups.com> wrote:
>
> On Tue, Feb 27, 2024 at 8:19 PM Marvin Renich <mr...@renich.org> wrote:
>
> Prior to generics, the type of the
> arguments to == were easily known to the programmer, and so it was
> obvious when this "undefined" exception would raise its ugly head, and
> you just didn't use it for empty struct types.  But now, with generics,
> this can only be classified as a glaring BUG in the spec.
>
>
> There is pretty much a 0% chance that we'd change the spec in this regard,
> at this point. It would mean that variable declarations like
> `[1<<30]struct{}` would have to allocate huge chunks of heap, to ensure
> that different index-expressions can have different addresses. And while
> there shouldn't be any code relying on that not happening for correctness,
> there is definitely code out there relying on it for performance (e.g.
> there is a pattern of adding struct fields like `_ [0]func()` to ensure a
> type is not comparable - such a struct would now change alignment and size).
>
> The optimization that variables of zero size can re-use the same address
> has been in Go since before Go 1. Given this, it is pretty much implied
> that comparison of those pointers will sometimes have weird results - the
> only question is, *which* results are weird. I agree that this is one of
> the weirder cases. But I don't think we can practically define `==` for
> pointers to zero-sized variables.
>
> I'll also point out that for generics specifically, I'm not sure *any*
> action would have a practical effect. If the type argument is not
> statically known, we also can't special-case it to take into account that
> it's a pointer to a zero-sized variable. Note that the triggered
> optimization isn't necessarily "these are pointers to zero-sized variables,
> hence I can do whatever I want" - it's "these are pointers to distinct
> variables, hence I can assume they are unequal". That is a generally useful
> optimization and it would still be applied to generic code.
>
> How can a programmer count on x == y having any meaning at all in code
> like this:
>
> func IsEqual[T comparable](x, y T) bool {
>     return x == y
> }
>
> if the definition of == for empty structs is undefined?
>
>
> The result is defined for empty structs, just not for *pointers* to empty
> structs.
> Note that `==` has other edge-cases as well. In particular, for floating
> point/complex type arguments, `==` is irreflexive (e.g. NaN is unequal to
> itself).
> I'm not sure that pointers to zero-sized variables make this significantly
> worse.
>
>
> If we can at least agree that this ambiguity is no longer desirable,
>
>
> I don't think we can agree on that, sorry.
>
>
> let's consider the two possible definitions:
>
> 1. Pointers to distinct zero-size variables are equal:
>
> This allows the compiler to easily optimize virtual address usage, but
> is inconsistent with the non-zero-size definition.
>
>
> Please look at the issue I filed for some discussion of edge-cases we are
> unlikely to be able to cover satisfactorily. One obvious case is when
> converting them to `unsafe.Pointer`, in which case the compiler no longer
> knows that they point at zero-sized variables. Potentially, any such
> conversion would have to re-assign them the magic "zero-sized variable"
> address, which then would potentially lead to other weird comparison
> implications, when code assumes that two `unsafe.Pointer` pointing at
> distinct variables should have distinct addresses.
>
> We could probably make *more* such comparisons evaluate to `true`, but
> it's unlikely that we could ever cover *all* of them. It would potentially
> have prohibitive performance-impact on slicing operations, for example.
>
> 2. Pointers to distinct zero-size variables are not equal:
>
> This is consistent with the non-zero-size definition, but the
> implementation would likely require distinct virtual addresses for
> distinct variables.  Whether this would require committed memory
> corresponding to those virtual addresses is unclear to me.
>
>
> I believe it would. In effect, `struct{}` would have to take at least one
> byte (as would a zero-sized array).
>
>
> Definition 1 removes the distinction between empty struct values and
> empty struct instances, and the only way for the programmer to get that
> distinction back is by using a non-empty struct.
>
> On the other hand, definition 2 preserves the distinction.  If a
> programmer wants to have instances compare as equal, it is often very
> easy to use instances of the empty type rather than instances of a
> pointer to the empty type.  Implement the methods on the type with value
> receivers rather than pointer receivers.
>
>
> I think if these arguments hold any water, the argument "the programmer
> just shouldn't use pointers to zero-sized variables, if they want defined
> semantics for ==" is just as valid. That is, if they have control over the
> type and we are willing to force them to make a decision aligning with our
> definition, why not force them to make a decision aligning with there not
> being a definition?
>
>
>
> ...Marvin
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/Zd41i3rHLskqBuef%40basil.wdw
> .
>
>
> --
>
> You received this message because you are subscribed to a topic in the
> Google Groups "golang-nuts" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/golang-nuts/JBVqWYFdtC4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHVuxSduyWHG20DjzG1jvE0P06fEqC_FyHdDEWewjOjTg%40mail.gmail.com
> <https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHVuxSduyWHG20DjzG1jvE0P06fEqC_FyHdDEWewjOjTg%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts...@googlegroups.com.
>
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c7ead734-8ce6-4254-91ac-771b02e527ddn%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/c7ead734-8ce6-4254-91ac-771b02e527ddn%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>
> --
> You received this message because you are subscribed to the Google Groups
> "golang-nuts" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to golang-nuts+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/golang-nuts/c7b44255-13f1-434d-b569-f592c8e262d4n%40googlegroups.com
> <https://groups.google.com/d/msgid/golang-nuts/c7b44255-13f1-434d-b569-f592c8e262d4n%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHJvxBpRHzrre8CryN9vJRcrM8H%3DifS5%3DBgELjsor7s3g%40mail.gmail.com.

Reply via email to