<p dir="auto">Go spec says:</p>
<blockquote>
<p dir="auto">For real and imag, the argument must be of complex type, and the return type is the corresponding floating-point type: float32 for a complex64 argument, and float64 for a complex128 argument. <strong>If the argument evaluates to an untyped constant, it must be a number, and the return value of the function is an untyped floating-point constant.</strong></p>
</blockquote>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ cat /tmp/cplx.go
package cplx

const (
        a int = real(0i)
        b = imag(0)
)
$ go tool compile /tmp/cplx.go
/tmp/cplx.go:4: cannot use real(0i) (type float64) as type int in const initializer
/tmp/cplx.go:5: invalid argument 0 (type int) for imag
$ gccgo-4.8 -c /tmp/cplx.go
$ gotype /tmp/cplx.go"><pre class="notranslate"><code class="notranslate">$ cat /tmp/cplx.go
package cplx

const (
        a int = real(0i)
        b = imag(0)
)
$ go tool compile /tmp/cplx.go
/tmp/cplx.go:4: cannot use real(0i) (type float64) as type int in const initializer
/tmp/cplx.go:5: invalid argument 0 (type int) for imag
$ gccgo-4.8 -c /tmp/cplx.go
$ gotype /tmp/cplx.go
</code></pre></div>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="package main
const _ int = real(10i)"><pre class="notranslate"><code class="notranslate">package main
const _ int = real(10i)
</code></pre></div>
<p dir="auto">=&gt;</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="$ go build x.go
# command-line-arguments
./x.go:2: cannot use real(10i) (type float64) as type int in const initializer"><pre class="notranslate"><code class="notranslate">$ go build x.go
# command-line-arguments
./x.go:2: cannot use real(10i) (type float64) as type int in const initializer
</code></pre></div>
<p dir="auto">(same for use of imag instead of real).</p>
<p dir="auto">It appears that real and imag always produce a float32 or float64 constant respectively, for untyped constant arguments. The spec is not explicit about this, but this behavior violates the invariant</p>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="z == complex(real(z), imag(z))"><pre class="notranslate"><code class="notranslate">z == complex(real(z), imag(z))
</code></pre></div>
<p dir="auto">for untyped constants z because real and imag won't work if the complex arguments have untyped constant components outside the float64 domain (see also <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="92743079" data-permission-text="Title is private" data-url="https://github.com/golang/go/issues/11540" data-hovercard-type="issue" data-hovercard-url="/golang/go/issues/11540/hovercard" href="https://github.com/golang/go/issues/11540">#11540</a> ).</p>
<p dir="auto">Both gc, and go/types accept this code. Both gc and go/types produce an untyped floating-point constant for untyped constant arguments.</p>