Open gafter opened 1 year ago
As documented here:
If all the fields of an immutable structure are indistinguishable (===) then two immutable values containing those fields are also indistinguishable: ...
I agree that similar sentences should be added the doc of ===
.
The doc and behavior is correct: tuples are immutable and calling pointer
on a tuple gives you something that may or may not be a meaningful number. If anything, the bug here is pointer
not erroring on a tuple.
FWIW, the pointer
call demonstrated there is on the String object, and we make few guarantees about how meaningful that value is and what can be done with it, but it is commonly necessary for C interop.
Ah, yes, pointer(::String)
is a bit unusual—it gives a pointer to memory that has the string data at it, but there's no guarantee of which pointer to such data or that it has anything to do with object identity.
The doc also says that "in the sense that no program could distinguish them", but the example in the issue showed that in some cases you could distinguish objects (by using pointer) even when ===
evaluates to true
.
As Stefan said, it does not uniquely distinguish the object. It gives an arbitrary such pointer, but not one that is necessary derived from the object in any meaningful way; it is not always repeatable; and it may or may not be unique.
specifically pointer(x)===pointer(x) may return false.
specifically pointer(x)===pointer(x) may return false.
@oscardssmith Can you please refer to where in the docs I can find information sufficient to infer this? If so, I will close this issue.
I found https://docs.julialang.org/en/v1/base/c/#Base.pointer but it doesn't give any hint of that.
https://docs.julialang.org/en/v1/base/c/#Base.pointer_from_objref says that this function may not be called on immutable objects, and it does indeed produce an error for must such. But it happily produces a pointer from a string.
julia> pointer("a")
Ptr{UInt8} @0x00007f77fe8b9dd0
julia> pointer("a")
Ptr{UInt8} @0x00007f77fe8ba298
This function is "unsafe"
is somewhat a hint (although we should probably add the specific weirdness with strings and malformed types).
I don't understand
===
. The doc says "First the types ofx
andy
are compared. If those are identical, mutable objects are compared by address in memory and immutable objects (such as numbers) are compared by contents at the bit level." But...It appears
t1 === t2
should befalse
, as they are not bitwise equal (they contain different pointers).Either the documentation is wrong (a bug that should be fixed) or the implementation is in error. I hope it is the documentation, which I suspect should say "First the types of
x
andy
are compared. If those are identical, mutable objects are compared by address in memory, primitive objects (such as numbers) are compared by contents at the bit level, and immutable objects are compared field-by-field using===
."