FAQ
This is related to the "How does the compiler treat static type
conversions?" thread.

I tried a simple code printing a const with numeric type and a value
overflowing int.

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

Should this fail?

Casting to int64 solves the problem, but it's still surprising (for me)
that this fails.

--
Francesc

--

Search Discussions

  • Rob Pike at Nov 5, 2012 at 7:58 pm
    It is a bug in your program. When stored somewhere (here in an
    argument slot) untyped integer constants are promoted to int, always,
    if there is no other type defined by the place they're going. Stop
    thinking like a C programmer.

    WIth amd64 at tip, your program will compile because ints are 64 bits.

    -rob

    --
  • Kevin Gillette at Nov 5, 2012 at 8:12 pm

    On Monday, November 5, 2012 12:58:57 PM UTC-7, Rob Pike wrote:

    Stop thinking like a C programmer.
    Another way of putting it is that Go doesn't really have 'casting' in the
    same sense that other languages might, and conversions are never implicit.
    When you passed x to fmt.Printf, it wasn't, strictly speaking, converted to
    an int, because it never was anything concrete before that to convert
    _from_ -- the distinction is made at compile time, and as Rob said, when
    the distinction must be made, integral untyped constants are promoted to
    'int'.

    --
  • Bryanturley at Nov 5, 2012 at 8:55 pm

    On Monday, November 5, 2012 2:12:42 PM UTC-6, Kevin Gillette wrote:
    On Monday, November 5, 2012 12:58:57 PM UTC-7, Rob Pike wrote:

    Stop thinking like a C programmer.
    Another way of putting it is that Go doesn't really have 'casting' in the
    same sense that other languages might, and conversions are never implicit.
    When you passed x to fmt.Printf, it wasn't, strictly speaking, converted to
    an int, because it never was anything concrete before that to convert
    _from_ -- the distinction is made at compile time, and as Rob said, when
    the distinction must be made, integral untyped constants are promoted to
    'int'.
    Well casting is casting, go has (almost?) no auto casting is the real
    difference.

    Though searching the spec I find zero instances of the word cast. It is in
    there as conversion.
    http://golang.org/ref/spec#Conversions

    Which confused me and led me to this
    http://en.wikipedia.org/wiki/Type_conversion

    notably this part
    "In most Algol-based languages with nested function definitions, such as
    Ada, Delphi, Modula 2 and Pascal, *conversion* and *casting* are distinctly
    different concepts. In these languages, *conversion* refers to either
    implicitly or explicitly changing a value from one data type to another,
    e.g. a 16-bit integer to a 32-bit integer. The storage requirements may
    change as a result of the conversion. A loss of precision or truncation may
    also occur. The word *cast*, on the other hand, refers to explicitly
    changing the *interpretation* of the *bit pattern* representing a value
    from one type to another. For example 32 contiguous bits may be treated as
    an array of 32 booleans, a two character Unicode string, an unsigned 32-bit
    integer or an IEEE single precision floating point value."

    But someone else is going to have to tell you how that relates to go's use
    of the word/concept conversion, or just read the go spec...

    --
  • Kevin Gillette at Nov 6, 2012 at 8:42 am

    On Monday, November 5, 2012 1:55:50 PM UTC-7, bryanturley wrote:

    Well casting is casting, go has (almost?) no auto casting is the real
    difference.

    "In most Algol-based languages with nested function definitions, such as
    Ada, Delphi, Modula 2 and Pascal, *conversion* and *casting* are
    distinctly different concepts. In these languages, *conversion* refers to
    either implicitly or explicitly changing a value from one data type to
    another, e.g. a 16-bit integer to a 32-bit integer. The storage
    requirements may change as a result of the conversion. A loss of precision
    or truncation may also occur. The word *cast*, on the other hand, refers
    to explicitly changing the *interpretation* of the *bit pattern*representing a value from one type to another. For example 32 contiguous
    bits may be treated as an array of 32 booleans, a two character Unicode
    string, an unsigned 32-bit integer or an IEEE single precision floating
    point value."
    Even C has the _semantic_ distinction between casting and conversion,
    though for most people, the notions are blurred because the same syntax is
    used for both, and last I checked, most people refer to them all as "casts".

    On the other hand, when you do a cast from char** to void* in C, that is
    indeed what wikipedia would call a "cast". When you cast a long into an
    int, unless you do some tricky intermediate stuff, that's actually a
    conversion (not a reinterpretation of the lower/upper half of the bits).
    It's, of course, much more obvious when working with assembly. Conversions
    in C are fairly uninteresting (any high level language that can't do
    conversions between semantically similar types has a lot of work to do if
    it wants to be called "useful"), which is probably why "casting" is misused
    to refer to conversions as well.

    In Go, there simply aren't 'casts' in the *interesting* C sense, since they
    would be memory unsafe -- in C, sure, you can cast that double into a
    `struct { a char*; b int; }` on a 386, but then you've got a junk pointer.
    The only way to accomplish these in Go is with unsafe.

    In some Go conversions, no actual modification of the value bits are
    needed, such as with:

    type AnotherInt int
    var x int = 5
    var y = AnotherInt(x)

    In this case, AnotherInt is trivially determined at compile time to have
    the same memory layout (not just total bit-width, but also semantics) as
    int, and so the conversion is essentially just a direct value copy as you
    would have with `z := y`, but under the guise of a different type name.
    This optimization only happens when the *value bits* don't need
    reinterpretation, which puts it outside the definition of 'casting', as
    offered above. This is also what makes the sort package types like IntSlice
    usable, since you don't have to copy the values in a loop
    (http://play.golang.org/p/tosmKQ5e8R).

    --
  • Francisco Souza at Nov 6, 2012 at 2:00 pm

    On Mon, Nov 5, 2012 at 6:12 PM, Kevin Gillette wrote:
    On Monday, November 5, 2012 12:58:57 PM UTC-7, Rob Pike wrote:

    Stop thinking like a C programmer.

    Another way of putting it is that Go doesn't really have 'casting' in the
    same sense that other languages might, and conversions are never implicit.
    Number conversions are never implicit.

    --
    ~f

    --
  • Francesc Campoy Flores at Nov 5, 2012 at 9:56 pm
    That makes sense, even for my my still severely C++ shaped brain.

    Thanks!

    On Mon, Nov 5, 2012 at 11:58 AM, Rob Pike wrote:

    It is a bug in your program. When stored somewhere (here in an
    argument slot) untyped integer constants are promoted to int, always,
    if there is no other type defined by the place they're going. Stop
    thinking like a C programmer.

    WIth amd64 at tip, your program will compile because ints are 64 bits.

    -rob


    --
    --
    Francesc

    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 5, '12 at 7:49p
activeNov 6, '12 at 2:00p
posts7
users5
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase