October 18, 2014
On Friday, 17 October 2014 at 13:44:24 UTC, ketmar via Digitalmars-d wrote:
> On Fri, 17 Oct 2014 09:46:48 +0000
> via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> In D (and C++) you would get:
>> 
>> if (x < ((x+1)&0xffffffff)){…}
> perfect. nice and straightforward way to do overflow checks.

Besides, the code uses x + 1, so the code is already in undefined state. It's just as wrong as the "horrible code with UB" we wère trying to avoid in the first place.

So much for convincing me that it's a good idea...
October 18, 2014
On Saturday, 18 October 2014 at 08:22:25 UTC, monarch_dodra wrote:
> On Friday, 17 October 2014 at 13:44:24 UTC, ketmar via Digitalmars-d wrote:
>> On Fri, 17 Oct 2014 09:46:48 +0000
>> via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>> In D (and C++) you would get:
>>> 
>>> if (x < ((x+1)&0xffffffff)){…}
>> perfect. nice and straightforward way to do overflow checks.

It wasn't an overflow check as ketmar suggested… It was a check that should stay true, always for this instantiation. So the wrong code is bypassed on overflow, possibly missing a termination. The code would have been correct with an optimization that set it to true or with a higher resolution register.

> Besides, the code uses x + 1, so the code is already in undefined state. It's just as wrong as the "horrible code with UB" we wère trying to avoid in the first place.
>
> So much for convincing me that it's a good idea...

Not sure if you are saying that modulo-arithmetic as a default is a bad or good idea?

In D and (C++ for uint) it is modulo-arithmetic so it is defined as a circular type with at discontinuity which makes reasoning about integers harder.
October 18, 2014
On 10/17/2014 2:46 AM, "Ola Fosheim Grøstad" <ola.fosheim.grostad+dlang@gmail.com>" wrote:
> It isn't even obvious that a byte should be 8 bits,

Oh come on!

http://dlang.org/type.html
October 18, 2014
On 10/16/2014 2:00 PM, bearophile wrote:
> Just found with Reddit. C seems one step ahead of D with this:
>
> http://developerblog.redhat.com/2014/10/16/gcc-undefined-behavior-sanitizer-ubsan/

On the other hand, D is one step ahead of C with many of those (they are part of the language, not an add-on tool).

Anyhow, for the remainder,

    https://issues.dlang.org/show_bug.cgi?id=13636
October 19, 2014
On Saturday, 18 October 2014 at 23:45:37 UTC, Walter Bright wrote:
> On 10/17/2014 2:46 AM, "Ola Fosheim Grøstad" <ola.fosheim.grostad+dlang@gmail.com>" wrote:
>> It isn't even obvious that a byte should be 8 bits,
>
> Oh come on!

Hey, that was a historically motivated reflection on the smallest addressable unit. Not obvious that it should be 8 bit. :9
October 19, 2014
On Saturday, 18 October 2014 at 23:10:15 UTC, Ola Fosheim Grøstad wrote:
> On Saturday, 18 October 2014 at 08:22:25 UTC, monarch_dodra wrote:
>> Besides, the code uses x + 1, so the code is already in undefined state. It's just as wrong as the "horrible code with UB" we wère trying to avoid in the first place.
>>
>> So much for convincing me that it's a good idea...
>
> Not sure if you are saying that modulo-arithmetic as a default is a bad or good idea?

Op usually suggested that all overflows should be undefined behavior, and that you could "pre-emptivelly" check for overflow with the above code. The code provided itself overflowed, so was also undefined.

What I'm pointing out is that working with undefined behavior overflow is exceptionally difficult, see later.

> In D and (C++ for uint) it is modulo-arithmetic so it is defined as a circular type with at discontinuity which makes reasoning about integers harder.

What interesting is that overflow is only defined for unsigned integers. signed integer overflow is *undefined*, and GCC *will* optimize away any conditions that rely on it.

One thing I am certain of, is that making overflow *undefined* is *much* worst than simple having modulo arithmetic. In particular, implementing trivial overflow checks is much easier for the average developper. And worst case scenario, you can still have library defined checked integers.
October 19, 2014
On 19 Oct 2014 09:40, "monarch_dodra via Digitalmars-d" < digitalmars-d@puremagic.com> wrote:
>
> On Saturday, 18 October 2014 at 23:10:15 UTC, Ola Fosheim Grøstad wrote:
>>
>> On Saturday, 18 October 2014 at 08:22:25 UTC, monarch_dodra wrote:
>>>
>>> Besides, the code uses x + 1, so the code is already in undefined
state. It's just as wrong as the "horrible code with UB" we wère trying to avoid in the first place.
>>>
>>> So much for convincing me that it's a good idea...
>>
>>
>> Not sure if you are saying that modulo-arithmetic as a default is a bad
or good idea?
>
>
> Op usually suggested that all overflows should be undefined behavior, and
that you could "pre-emptivelly" check for overflow with the above code. The code provided itself overflowed, so was also undefined.
>
> What I'm pointing out is that working with undefined behavior overflow is
exceptionally difficult, see later.
>
>
>> In D and (C++ for uint) it is modulo-arithmetic so it is defined as a
circular type with at discontinuity which makes reasoning about integers harder.
>
>
> What interesting is that overflow is only defined for unsigned integers.
signed integer overflow is *undefined*, and GCC *will* optimize away any conditions that rely on it.
>

Good thing that overflow is strictly defined in D then. You can rely on overflowing to occur rather than be optimised away.

Iain.


October 19, 2014
On Friday, 17 October 2014 at 10:50:54 UTC, Ola Fosheim Grøstad wrote:
> On Friday, 17 October 2014 at 10:30:14 UTC, eles wrote:
>> On Friday, 17 October 2014 at 09:46:49 UTC, Ola Fosheim Grøstad wrote:

>>
>> Nice idea, but how to persuade libraries to play that game?
>
> 1. Provide a meta-language for writing propositions that describes what libraries do if they are foreign (pre/post conditions). Could be used for "asserts" too.

That's complicated, to provide another langage for describing the behavior. And how? Embedded in the binary library?

Maybe a set of annotations that are exposed through the .di files. But, then, we are back to headers...

Another idea would be to simply make the in and out contracts of a function exposed in the corresponding .di file, or at least a part of them (we could use "public" for those).

Anyway, as far as I ca imagine it, it would be like embedding Polyspace inside the compiler and stub functions inside libraries.

> 2. Provide a C compiler that compiles to the same internal representation as the new language, so you can run the same analysis on C code.

For source code. But for cloused-source libraries?

> 3. Remove int so that you have to specify the range and make typedefs local to the library

Pascal arrays?

> Lots of opportunities for improving "state-of-the-art".

True. But a lot of problems too. And there is not much agreement on what is the state of the art...
October 19, 2014
On Sunday, 19 October 2014 at 08:37:54 UTC, monarch_dodra wrote:
> On Saturday, 18 October 2014 at 23:10:15 UTC, Ola Fosheim Grøstad wrote:
>> In D and (C++ for uint) it is modulo-arithmetic so it is defined as a circular type with at discontinuity which makes reasoning about integers harder.
>
> What interesting is that overflow is only defined for unsigned integers. signed integer overflow is *undefined*, and GCC *will* optimize away any conditions that rely on it.

I don't agree with how C/C++ defines arithmetics. I think integers should exhibit monotonic behaviour over addition and multiplication and that the compiler should assume, prove or assert that assigned values are within bounds according to the programmer's confidence and specification.

It is the programmers' responsibility to make sure that results stays within the type boundaries or to configure the compiler so that they will be detected.

If you provide value-ranges for integers then the compiler could flag all values that are out of bounds and force the programmer to explicitly cast them back to the restricted type.

If you default to 64 bit addition then getting overflows within simple expressions is not the most common problem.

> One thing I am certain of, is that making overflow *undefined* is *much* worst than simple having modulo arithmetic. In particular, implementing trivial overflow checks is much easier for the average developper. And worst case scenario, you can still have library defined checked integers.

One big problem with that view is that  "a < a+1" is not an overflow check, it is the result of aliasing. It should be optimized to true. That is the only sustainable interpretation from a correctness point of view.

Even if  "a < a+1" is meant to be an overflow check it completely fails if a is a short since it is promoted to int. So this is completely stuck in 32-bit land.

In C++ you should default to int and avoid uint unless you do bit manipulation according to the C++ designers.

There are three reasons: speed, portability to new hardware and correctness.
October 19, 2014
On Sunday, 19 October 2014 at 09:56:44 UTC, Ola Fosheim Grøstad wrote:
> In C++ you should default to int and avoid uint unless you do bit manipulation according to the C++ designers.
>
> There are three reasons: speed, portability to new hardware and correctness.

Speed: How so?

Portability: One issue to keep in mind is that C works on *tons* of hardware. C allows hardware to follow either two's complement, or one's complement. This means that, at best, signed overflow can be implementation defined, but not defined by spec. Unfortunately, it appears C decided to outright go the undefined way.

Correctness: IMO, I'm not even sure. Yeah, use int for numbers, but stick to size_t for indexing. I've seen too many bugs on x64 software when data becomes larger than 4G...