-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Closed
Labels
Description
$ cat x.go package main var s uint var x = 1<<s != 0.1 $ gccgo x.go x.go:3:12: error: shift of non-integer operand var x = 1.0<<s != 0.1 ^ But it should say instead: x.go:3:16: error: floating point constant truncated to integer (see also issue #4880, same case for 6g) Rationale: This is a non-constant shift (s is a variable) of an untyped constant (1) on the lhs, used in a comparison. The spec says ( http://tip.golang.org/ref/spec#Operators ): "If the left operand of a non-constant shift expression is an untyped constant, the type of the constant is what it would be if the shift expression were replaced by its left operand alone; the type is int if it cannot be determined from the context (for instance, if the shift expression is an operand in a comparison against an untyped constant)." The type of the lhs constant 1 in the shift depends on the context of the shift. We are in a comparison, and the rhs of the comparison is another untyped constant (0.1). Thus, per spec, the type of 1 cannot be determined from context and is int. So 1<<s in this case is an int value. It cannot be compared against 0.1 because 0.1 cannot be represented as an int. Hence the error message should complain about 0.1 and not the shift. However, it appears as if the compiler tries to convert the 1 to the default type of 0.1, which is float64. Comparisons are singled out as special case in shifts. Here's another example supporting this reasoning: var s uint var x = 1.0<<s != 0 is accepted by 6g (this example is from the spec, same section). This is the same situation but the 1.0 is not promoted to a float64 because it's within a comparison, and the thus gets the type int. gccgo does not accept this case either: x.go:3:12: error: invalid context-determined non-integer type for left operand of shift var x = 1.0<<s != 0 ^