Home > Net >  Why isn't the compiler warning about incorrect formatters?
Why isn't the compiler warning about incorrect formatters?

Time:01-08

I was expecting the following code to at least raise a warning during compilation because the formatters are not aligned with the types of variables:

package main

import "fmt"

func main() {
    s := "hello"
    fmt.Printf("1 %w", s)
    fmt.Printf("2 %s", s)
}

The types of the variables are known at compile time, and the string formatters are parsed in a deterministic way - is there a reason why the error is not raised at that point?

What I get instead is a code that outputs

1 %!w(string=hello)2 hello

This seems to be some kind of message telling that %w was wrong for the type string (but only at runtime)

CodePudding user response:

The fmt.Printf format string argument is interpreted at runtime, not compile time.

func Printf(format string, a ...any) (n int, err error)

Printf formats according to a format specifier and writes to standard output. It returns the number of bytes written and any write error encountered.

Use a static analysis linter, for example, go vet.

go command - cmd/go - Go Packages

Report likely mistakes in packages

Usage:

go vet [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]

Vet runs the Go vet command on the packages named by the import paths.

For more about vet and its flags, see 'go doc cmd/vet'.


so.go:

package main

import "fmt"

func main() {
    s := "hello"
    fmt.Printf("1 %w\n", s)
    fmt.Printf("2 %s\n", s)
}

linter:

$ go vet so.go
./so.go:7:2: fmt.Printf format %w has arg s of wrong type string, 
             see also https://pkg.go.dev/fmt#hdr-Printing
$ 

runtime:

$ go run so.go
1 %!w(string=hello)
2 hello
$ 
  • Related