-
Notifications
You must be signed in to change notification settings - Fork 18k
proposal: sync/atomic: deprecate AddXxx, CompareAndSwapXxx, LoadXxx, StoreXxx, SwapXxx #55302
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
Comments
Here's a reason to not deprecate them: if an existing exported struct type has an
We could still add a hint to the old APIs to point out that the new named types exist, though. |
I don't think there is any need to deprecate the old functions. They work. There's nothing wrong with them. I think if someone was starting a new codebase they should use the new types+methods, but in existing codebases there's no reason to force/nudge people to use the new way. |
The old way is more memory efficient than new ways on 32-bit architectures, which is another reason it should not be deprecated. |
That doesn't seem right; I thought that part of the reason these types were added was so they'd get compiler support to prevent misalignment on those architectures. You might get a smaller struct if you don't use them, but your atomic operations might not work either, right? |
@mvdan, it's true that changing the type of an existing field would be a breaking change, but “avoiding a breaking API change” is IMO one of the few good reasons to add new usage of a deprecated API. |
I guess that's true of the 32-bit functions, but for the 64-bit functions there is a prominent It may be true that “they work” subject to that caveat, but that seems like a far cry from “nothing wrong with them”. 😅 The |
@bcmills I guess you're right. By my reasoning that switching to (or from) any named type can be a breaking change, we would never be able to deprecate a type. But that's clearly not right; sometimes there are good reasons to deprecate a type. |
Doesn't “deprecate” imply exactly that — avoid in new code, still works for existing code? (That's certainly how I interpret it, but maybe I've spent too long in Google's codebases. 🤔) |
I think there's a slight disconnect because some people treat deprecation notices as more imperative. For example, staticcheck uses them as warnings, and some people like me treat staticcheck warnings as CI errors. I would have to go out of my way to tell staticcheck that, in a particular case, that deprecation warning is OK to keep because I must follow semver. Which I guess is fine for the edge case - but that is why "still works for existing code" isn't true out of the box for any staticcheck users. |
Which cases are more memory-efficient? The new way does force correct alignment for 64-bit fields, but the implementation of the old functions also requires the user to manually perform that same alignment in portable code. |
I would be ok with deprecating just the 64-bit ops on 32-bit platforms. |
On 32-bit architectures
If C and D are used as array elements, then the latter will consume more memory. type A struct {
x int64
y int32
}
type B struct {
x atomic.Int64
y int32
}
type C struct {
A
x int32
}
type D struct {
B
x int32
} |
Is that a bug in the compiler implementation of The documentation for
but I don't see anything that would require |
Maybe the implemenation is to satisfy |
If I'm reading the current (That's because |
I'm not sure whether or not it is a bug. package main
import (
"sync/atomic"
"unsafe"
)
type T struct {
_ [0]atomic.Int64
x int32
}
type A struct {
T
v int32
}
type B struct {
_ [0]atomic.Int64
x int32
v int32
}
func main() {
println(unsafe.Sizeof(A{}), unsafe.Sizeof(B{})) // 16 8
} |
@go101 That is not a bug. At least, it is intentional. The Go compiler does not attempt to pack some fields into padding needed by other fields. It is possible we could do that, but it gets tricky. For instance, this program prints 0:
The compiler is currently fast-and-loose with data in padding fields - in this case it is easier to zero a |
Deprecate in Go means that we show a warning for code that uses the existing functions. The old atomics are not broken enough to warrant that kind of warning and the developer time that dealing with the warnings will consume. (Compare to deprecating MD5, or deprecating math/rand.Read - those are far more likely to be real problems in programs.) |
This proposal has been added to the active column of the proposals project |
Based on the discussion above, this proposal seems like a likely decline. |
No change in consensus, so declined. |
Go 1.19 defines new atomic types Bool, Int32, Int64, Uint32, Uint64, Uintptr, and Pointer (release note)
Using these types is more convenient and secure than using AddXxx, CompareAndSwapXxx, LoadXxx, StoreXxx, SwapXxx.
(ex. func AddInt32(addr *int32, delta int32) (new int32))
Moreover, the performance is almost the same, we do not believe there are any situations where AddXxx, CompareAndSwapXxx, LoadXxx, StoreXxx, SwapXxx should be used, and deprecation would limit the user's choices and improve the experience.
Is there a reason that we can not deprecate these functions?
The text was updated successfully, but these errors were encountered: