Skip to content
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

encoding/gob: Encode not called for wrapped struct with only zero values inside #56864

Closed
aljasPOD opened this issue Nov 21, 2022 · 1 comment

Comments

@aljasPOD
Copy link

  1. What version of Go are you using (go version)?
    1.19
  2. What operating system and processor architecture are you using?
    Initially found on Windows 10, x64, but also reproducible on go.dev/play
  3. What did you do?
    Create a struct with single int-typed private field and a custom GobEncode() method for it.
    Use said struct in another struct as a public field, and try to encode the external struct with gob.
    Overly simplified version: https://go.dev/play/p/iRRTIzvixOk
  4. What did you expect to see?
    GobEncode() gets called on Structy when the wrapping struct is encoded.
  5. What did you see instead?
    GobEncode() did not get called.

Doing more experimentation (see https://go.dev/play/p/gugr1jzmAtz):

  • inp1: if the struct isn't a field in another struct the function gets called
  • inp2: (original case)
  • inp3: if the value in the struct is not 0, the encode function gets called
  • inp4: the function does not get called regardless of other fields having (non-zero) value in the wrapping struct
  • inp5: the function gets called if the wrapping struct has a pointer for the wrapped struct
  • inp6: the internal struct has multiple fields, all zero valued, the custom GobEncode is not called
  • inp7: the other internal field has a non-zero value, GobEncode is called

My guess is that this behavior is related to the struct being the zero value of its type. I'm not entirely convinced if this is a bug or just an "expected" side-effect of zero values, in the later case it would be good to call this out in the documentation for GobEncode(), as this doesn't really feel like complete control. It is definitely confusing at first glance that it only happens in some of the cases.

Some context on the actual use case this is coming from:

  • The struct with the private field is an enum-like type, the goal is to prevent invalid values showing up ~ever (so 0 has to be one of the valid ones, as someone can create the struct itself, but not directly set the value - it isn't perfect, but much better than just creating a type that is just int, where one can use any constant as a value).
  • The encoding actually maps the values to the strings versions of the enum values in GobEncode(), so the enum to int mapping can change without needing to keep the two sides talking in sync / compiled from the same version (the code for this part is generated)

As a workaround I can add a second field containing a dummy non-zero value to the enum struct, (luckily when the enum struct is inside another one there is some other processing done on it before being output, so even if a completely zero struct is created the dummy field can still be filled in before being handed to gob).

@mengzhuo mengzhuo changed the title GobEncode not called for wrapped struct with only zero values inside encoding/gob: Encode not called for wrapped struct with only zero values inside Nov 21, 2022
@robpike
Copy link
Contributor

robpike commented Nov 21, 2022

The package does not encode zero values. This is expected behavior, however undesired in this case.

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Nov 21, 2022
@golang golang locked and limited conversation to collaborators Nov 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants