flag: bug with shared values?

188 views
Skip to first unread message

Manfred Touron

unread,
Sep 17, 2020, 8:05:07 PM9/17/20
to golang-nuts
Hi,

I think that I discovered a bug in the stdlib flag package:

    sharedFlag := "init-value"
    fooFs := flag.NewFlagSet("foo", flag.ContinueOnError)
    barFs := flag.NewFlagSet("bar", flag.ContinueOnError)
    fooFs.StringVar(&sharedFlag, "baz", "foo-default", "testing")
    barFs.StringVar(&sharedFlag, "baz", "bar-default", "testing")
    _ = fooFs.Parse([]string{""}) // no error
    fmt.Println(*sharedFlag) // bar-default, instead of foo-default

To quote @peterbourgon on this issue:

> Haha! This is a bug (?) with stdlib flag.FlagSet.
> The default value provided to e.g. fs.StringVar isn't kept as metadata associated with the flag in the corresponding flagset, but is rather assigned to the associated variable. And that assignment happens at declaration time, when you call fs.StringVar, and not when you call fs.Parse. So the default value you see in any flag set will be the default value provided to whichever StringVar declaration happens to occur last — in your test, it's this one.
> This sucks.
> I think the only fix here would be, somehow, avoiding assigning a default value in the declaration, and populating it later. Or defining a separate e.g. DeferredFlagVar type that encapsulated this behavior? I don't know offhand what's best. Ugh.

I never contributed to the go repo yet, so I prefer to ask here your opinion about this strange behavior, what you suggest in term of fix that does not require to touch the stdlib, and if you think that I need to issue a bug on the go repo and try to contribute a fix?

Thank you,

Ian Lance Taylor

unread,
Sep 17, 2020, 8:23:04 PM9/17/20
to Manfred Touron, golang-nuts
What you say is true and I can see how it would be surprising but I
don't personally consider this to be a bug. It's a design decision.
Perhaps it should be documented more clearly: don't use the same
variable for more than one XXXVar calls.

Ian

Manfred Touron

unread,
Sep 18, 2020, 3:50:30 AM9/18/20
to golang-nuts
There are actually multiple cases of reusing the same XXXVar for the same variables:

* projects with multiple flag.FlagSet (to manage various subcommands in the same binary), that shares various common flags, i.e. `--verbose` so they can globally configure their logger against the same variable

What is unusual and problematic in my case, is that I don't use the same default value (third param).

Bug or not, I would like to know:

1. if I need to open an issue or not on the go repo, if the fix is not about code, it can be about doc maybe?
2. if other gophers has ideas of workaround?

Thank you

Ian Lance Taylor

unread,
Sep 18, 2020, 2:30:35 PM9/18/20
to Manfred Touron, golang-nuts
On Fri, Sep 18, 2020 at 12:50 AM Manfred Touron <m...@42.am> wrote:
>
> 1. if I need to open an issue or not on the go repo, if the fix is not about code, it can be about doc maybe?

Documentation fixes are always welcome. You can open an issue or just
send a change.

> 2. if other gophers has ideas of workaround?

I don't understand why it is important for these two different flags
to share the same variable.

Ian

Michael Jones

unread,
Sep 18, 2020, 6:43:57 PM9/18/20
to Ian Lance Taylor, Manfred Touron, golang-nuts

2. if other gophers has ideas of workaround?

Use distinct values, but never access them directly.

Write setter/getter functions that do the value sharing as you prefer and return the desired result.

--
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/CAOyqgcU9cMZnf4PaozoBEa4kL7DJgK1PDmnkibDmQ%2BLhbgm%3DJw%40mail.gmail.com.


--
Michael T. Jones
michae...@gmail.com
Reply all
Reply to author
Forward
0 new messages