Cast windows enum from signed to unsigned

310 views
Skip to first unread message

Archos

unread,
May 17, 2013, 7:48:19 PM5/17/13
to golan...@googlegroups.com
I can not cast a windows enum for a signed value.

To convert from:
    #define HWND_MESSAGE ((HWND)(-3))

I've tried:
    const _HWND_MESSAGE syscall.Handle = syscall.Handle(uint(-3))

and also, using `uint(int(-3))`

but I get: "constant -3 overflows uint"

Tad Glines

unread,
May 17, 2013, 9:08:42 PM5/17/13
to Archos, golang-nuts
It looks like you cannot underflow/overflow constants.
This works, but it isn't constants.
var X uint = 0
var Y uint = 3
var VAL uint = X - Y

As an alternative you can do:
const X uint32 = 0xFFFFFFFF-2
or
const X uint64 = 0xFFFFFFFFFFFFFFFF-2

but that's a bit opaque





--
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.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

peterGo

unread,
May 17, 2013, 11:27:45 PM5/17/13
to golan...@googlegroups.com
Archos,

// #define HWND_MESSAGE ((HWND)(-3))

const HWND_MESSAGE = -3

const _HWND_MESSAGE syscall.Handle = ^syscall.Handle(0) - (-HWND_MESSAGE) + 1

Peter

Rob Pike

unread,
May 18, 2013, 12:08:24 AM5/18/13
to peterGo, golan...@googlegroups.com
There is no unsigned integer representation of -3, there are only
fixed-size bit patterns of a given size that represent the same value
as a signed -3 of the same size.

http://play.golang.org/p/3UizlCMBXy

-rob

Tad Glines

unread,
May 18, 2013, 12:33:35 AM5/18/13
to Rob Pike, peterGo, golan...@googlegroups.com
The thing that confuses me is why this works:
    var x = -3
    var y uint32 = uint32(x)
but this doesn't:
    var y uint32 = uint32(int(-3))

They appear to be semantically the same.

What is the rationale for preventing the latter but not the former?



peterGo

unread,
May 18, 2013, 8:37:32 AM5/18/13
to Tad Glines, Rob Pike, golan...@googlegroups.com
Tad,

Go has two distinct number representation, conversion, and arithmetic
systems: one system for constants, which is used by the compiler, and
one system for variables, which is used at run time. Numeric constants
represent values of arbitrary precision and do not overflow. Constants
may be typed or untyped. Numeric variables (integer, floating point,
and complex) represent values of fixed precision and can overflow.
Variables are typed. Numeric variables follow the IEEE 754 standard,
constants do not.

var x = -3
var y uint32 = uint32(x)

The variable x is of type int. When converting between non-constant
integer types, if the value is a signed integer, it is sign extended
to implicit infinite precision; otherwise it is zero extended. It is
then truncated to fit in the result type's size. The conversion always
yields a valid value; there is no indication of overflow. Therefore,
uint32(x) is a valid variable conversion.

// constant -3 overflows uint32
var y uint32 = uint32(int(-3))

As the compiler explains, int(-3) is a constant of type int.
Therefore, uint32(int(-3)) is not a valid constant conversion, it
overflows.

The Go Programming Language Specification
http://golang.org/ref/spec

Peter

peterGo

unread,
May 18, 2013, 10:00:38 AM5/18/13
to Rob Pike, golan...@googlegroups.com
Rob,

For the original question, the type is defined by the implementation:
type Handle uintptr.

http://play.golang.org/p/fvtMrQCYiT

Peter

peterGo

unread,
May 18, 2013, 12:14:17 PM5/18/13
to golan...@googlegroups.com
Archos,

For negative, zero, and positive integer values,

// #define HWND_MESSAGE ((HWND)(-3))

const uintptrBits = uint((1 + ^uintptr(0)>>32&1) * 32)

const HWND_MESSAGE = -3

const _HWND_MESSAGE syscall.Handle = HWND_MESSAGE & (1<<uintptrBits - 1)

Peter

Tad Glines

unread,
May 18, 2013, 12:24:32 PM5/18/13
to peterGo, Rob Pike, golan...@googlegroups.com
OK, got it. Thanks for the clarification.

Rob Pike

unread,
May 18, 2013, 1:10:40 PM5/18/13
to Tad Glines, peterGo, golan...@googlegroups.com
Be careful. The size of uint is not the same as the size of uintptr on
arm and 386.

-rob
Reply all
Reply to author
Forward
Message has been deleted
0 new messages