golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.27k stars 17.47k forks source link

fmt: inconsistent pointer formatting with b/d/o/x/X verbs #65753

Open zoltanhalassy opened 6 months ago

zoltanhalassy commented 6 months ago

Go version

Playground Go 1.22

Output of go env in your module/workspace:

Playground 1.22 go env

What did you do?

https://go.dev/play/p/ivQo1wTK4NM

What did you see happen?

0xc000014070 &{%!b(string=baz)} &{%!d(string=baz)} &{%!o(string=baz)} &{62617a} &{62617A}

What did you expect to see?

https://pkg.go.dev/fmt#hdr-Printing for go1.22.0 states:

The %b, %d, %o, %x and %X verbs also work with pointers, formatting the value exactly as if it were an integer.

Either the documentation should be fixed or the behavior of fmt.

seankhliao commented 6 months ago

seems to work with primitive types like pointers to bool/string/int, but not for composite types like slices, maps, and structs.

cc @robpike

robpike commented 6 months ago

The cited documentation is irrelevant to the issue, as you can see if you try the program without taking the address of the struct: you see the same behavior.

Now the question is, should the formats recur into the fields of a struct? They do not, and doing so would rarely be the right thing to do. Whether the documentation needs work here I'm not sure, but the paragraph you cite is irrelevant, as I said.

robpike commented 6 months ago

Have a look at https://go.dev/play/p/HnO93o9-oao

The particular problem cited in this issue is that formats propagate for integer values but not strings, although as the example shows it would be rarely useful for them to do so.

That's probably fixable, but also probably not worthwhile.

seankhliao commented 6 months ago

the format also works for books and strings though https://go.dev/play/p/MSCt54fX00c I think the expectation is that it doesn't look into the value, just print the pointer address

zoltanhalassy commented 6 months ago

The cited documentation is irrelevant to the issue

Sorry, there might be a misunderstanding. The original title for the report was "fmt: Pointer formatting behavior doesn't match documentation". I don't have an opinion how the code should behave, just it doesn't behave as documented.

if you try the program without taking the address of the struct: you see the same behavior

A struct value is not a pointer; so the section "Pointer:" doesn't apply, and the section below that called "For compound objects, ..." applies, that's consistent.

If you think the code is working as intended, I'm fine with that. In that case I suggest the following changes to the documentation (emphasis on the changes):

Pointer: %p base 16 notation, with leading 0x The %b, %d, %o, %x and %X verbs also work with pointers to non-compound objects, formatting the value exactly as if it were an integer.

and below

For compound objects, and pointers to compound objects, the elements are printed using these rules, ...