Most active commenters

    ←back to thread

    288 points Twirrim | 17 comments | | HN request time: 1.114s | source | bottom
    Show context
    WalterBright ◴[] No.41875254[source]
    D made a great leap forward with the following:

    1. bytes are 8 bits

    2. shorts are 16 bits

    3. ints are 32 bits

    4. longs are 64 bits

    5. arithmetic is 2's complement

    6. IEEE floating point

    and a big chunk of wasted time trying to abstract these away and getting it wrong anyway was saved. Millions of people cried out in relief!

    Oh, and Unicode was the character set. Not EBCDIC, RADIX-50, etc.

    replies(6): >>41875486 #>>41875539 #>>41875878 #>>41876632 #>>41878715 #>>41881672 #
    1. Laremere ◴[] No.41875878[source]
    Zig is even better:

    1. u8 and i8 are 8 bits.

    2. u16 and i16 are 16 bits.

    3. u32 and i32 are 32 bits.

    4. u64 and i64 are 64 bits.

    5. Arithmetic is an explicit choice. '+' overflowing is illegal behavior (will crash in debug and releasesafe), '+%' is 2's compliment wrapping, and '+|' is saturating arithmetic. Edit: forgot to mention @addWithOverflow(), which provides a tuple of the original type and a u1; there's also std.math.add(), which returns an error on overflow.

    6. f16, f32, f64, f80, and f128 are the respective but length IEEE floating point types.

    The question of the length of a byte doesn't even matter. If someone wants to compile to machine whose bytes are 12 bits, just use u12 and i12.

    replies(6): >>41876011 #>>41876015 #>>41876480 #>>41876942 #>>41877281 #>>41878278 #
    2. __turbobrew__ ◴[] No.41876011[source]
    This is the way.
    3. Spivak ◴[] No.41876015[source]
    How does 5 work in practice? Surely no one is actually checking if their arithmetic overflows, especially from user-supplied or otherwise external values. Is there any use for the normal +?
    replies(1): >>41876229 #
    4. dullcrisp ◴[] No.41876229[source]
    You think no one checks if their arithmetic overflows?
    replies(1): >>41876357 #
    5. Spivak ◴[] No.41876357{3}[source]
    I'm sure it's not literally no one but I bet the percent of additions that have explicit checks for overflow is for all practical purposes indistinguishable from 0.
    replies(1): >>41876729 #
    6. notfed ◴[] No.41876480[source]
    Same deal with Rust.
    replies(1): >>41878431 #
    7. nox101 ◴[] No.41876729{4}[source]
    Lots of secure code checks for overflow

        fillBufferWithData(buffer, data, offset, size)
    
    You want to know that offset + size don't wrap past 32bits (or 64) and end up with nonsense and a security vulnerability.
    8. mort96 ◴[] No.41876942[source]
    Eh I like the nice names. Byte=8, short=16, int=32, long=64 is my preferred scheme when implementing languages. But either is better than C and C++.
    replies(1): >>41878505 #
    9. Cloudef ◴[] No.41877281[source]
    Zig allows any uX and iX in the range of 1 - 65,535, as well as u0
    replies(1): >>41880263 #
    10. Someone ◴[] No.41878278[source]
    LLVM has:

    i1 is 1 bit

    i2 is 2 bits

    i3 is 3 bits

    i8388608 is 2^23 bits

    (https://llvm.org/docs/LangRef.html#integer-type)

    On the other hand, it doesn’t make a distinction between signed and unsigned integers. Users must take care to use special signed versions of operations where needed.

    11. loup-vaillant ◴[] No.41878431[source]
    I've heard that Rust wraps around by default?
    replies(1): >>41878612 #
    12. shiomiru ◴[] No.41878505[source]
    It would be "nice" if not for C setting a precedent for these names to have unpredictable sizes. Meaning you have to learn the meaning of every single type for every single language, then remember which language's semantics apply to the code you're reading. (Sure, I can, but why do I have to?)

    [ui][0-9]+ (and similar schemes) on the other hand anybody can understand at the first glance.

    13. Measter ◴[] No.41878612{3}[source]
    Rust has two possible behaviours: panic or wrap. By default debug builds with panic, release builds with wrap. Both behaviours are 100% defined, so the compiler can't do any shenanigans.

    There are also helper functions and types for unchecked/checked/wrapping/saturating arithmetic.

    14. renox ◴[] No.41880263[source]
    u0?? Why?
    replies(3): >>41880597 #>>41885321 #>>41885460 #
    15. xigoi ◴[] No.41880597{3}[source]
    To avoid corner cases in auto-generated code?
    16. Cloudef ◴[] No.41885321{3}[source]
    To represent 0 without actually storing it in memory
    17. whs ◴[] No.41885460{3}[source]
    Sounds like zero-sized types in Rust, where it is used as marker types (eg. this struct own this lifetime). It also can be used to turn a HashMap into a HashSet by storing zero sized value. In Go a struct member of [0]func() (an array of function, with exactly 0 members) is used to make a type uncomparable as func() cannot be compared.