Thread overview
December 10, 2016
I'm pretty sure the following code should work, but it doesn't.

```
bool intersect(ptrdiff_t targetX, ptrdiff_t targetY, size_t targetWidth, size_t targetHeight, ptrdiff_t x, ptrdiff_t y, size_t width, size_t height)
{
 return targetX < x + width &&
       x < targetX + targetWidth &&
       targetY < y + height &&
       y < targetY + targetHeight;
}

void main() {
	import std.stdio;
	writeln(intersect(0,0,800,600,     0,150,148,148));
	writeln(intersect(0,0,800,600,     -10,150,148,148));
}
```

It outputs:
```
true
false
```

On the contrary if you write the same piece of code in other languages ex. C#

(Ran it through Linqpad)
```
bool intersect(int targetX, int targetY, uint targetWidth, uint targetHeight, int x, int y, uint width, uint height)
{
 return targetX < x + width &&
       x < targetX + targetWidth &&
       targetY < y + height &&
       y < targetY + targetHeight;
}

void Main() {
	intersect(0,0,800,600,     0,150,148,148).Dump();
	intersect(0,0,800,600,     -10,150,148,148).Dump();
}
```

Then it outputs:
```
true
true
```

Is it a bug or is it intended behavior?


December 10, 2016
On Saturday, 10 December 2016 at 08:09:00 UTC, Is it possible to store different generic types? wrote:
> I'm pretty sure the following code should work, but it doesn't.
>
> ```
> bool intersect(ptrdiff_t targetX, ptrdiff_t targetY, size_t targetWidth, size_t targetHeight, ptrdiff_t x, ptrdiff_t y, size_t width, size_t height)
> {
>  return targetX < x + width &&
>        x < targetX + targetWidth &&
>        targetY < y + height &&
>        y < targetY + targetHeight;
> }
>
> void main() {
> 	import std.stdio;
> 	writeln(intersect(0,0,800,600,     0,150,148,148));
> 	writeln(intersect(0,0,800,600,     -10,150,148,148));
> }
> ```
>
> It outputs:
> ```
> true
> false
> ```
>
> On the contrary if you write the same piece of code in other languages ex. C#
>
> (Ran it through Linqpad)
> ```
> bool intersect(int targetX, int targetY, uint targetWidth, uint targetHeight, int x, int y, uint width, uint height)
> {
>  return targetX < x + width &&
>        x < targetX + targetWidth &&
>        targetY < y + height &&
>        y < targetY + targetHeight;
> }
>
> void Main() {
> 	intersect(0,0,800,600,     0,150,148,148).Dump();
> 	intersect(0,0,800,600,     -10,150,148,148).Dump();
> }
> ```
>
> Then it outputs:
> ```
> true
> true
> ```
>
> Is it a bug or is it intended behavior?
Okay the issue seem to be that D casts the left-hand argument to the same type as the right-hand argument.

So when ex. doing "targetX < x + width" then it actually does "targetX < cast(width_type)x + width"

Where as I'd believe the behavior should have been "targetX < x + cast(x_type)width"

December 10, 2016
On Saturday, 10 December 2016 at 08:16:48 UTC, Is it possible to store different generic types? wrote:
> On Saturday, 10 December 2016 at 08:09:00 UTC, Is it possible to store different generic types? wrote:
>> [...]
> Okay the issue seem to be that D casts the left-hand argument to the same type as the right-hand argument.
>
> So when ex. doing "targetX < x + width" then it actually does "targetX < cast(width_type)x + width"
>
> Where as I'd believe the behavior should have been "targetX < x + cast(x_type)width"

Simply don't mix signed and unsigned types.
That is begging for trouble.
or convert them to the next highter signed type.
December 10, 2016
On 12/10/2016 12:16 AM, Is it possible to store different generic types? wrote:

> Okay the issue seem to be that D casts the left-hand argument to the
> same type as the right-hand argument.

Seems to be but not true. It's more like "anything that touches an unsigned type turns unsigned". :)

  https://dlang.org/spec/type.html#integer-promotions

The more important topic there is the second one: "Usual Arithmetic Conversions"

Ali

December 10, 2016
On Saturday, 10 December 2016 at 08:21:17 UTC, Stefan Koch wrote:
> On Saturday, 10 December 2016 at 08:16:48 UTC, Is it possible to store different generic types? wrote:
>> On Saturday, 10 December 2016 at 08:09:00 UTC, Is it possible to store different generic types? wrote:
>>> [...]
>> Okay the issue seem to be that D casts the left-hand argument to the same type as the right-hand argument.
>>
>> So when ex. doing "targetX < x + width" then it actually does "targetX < cast(width_type)x + width"
>>
>> Where as I'd believe the behavior should have been "targetX < x + cast(x_type)width"
>
> Simply don't mix signed and unsigned types.
> That is begging for trouble.
> or convert them to the next highter signed type.

Yeah, that's what I'm doing now. It seems like concepts of casting from other languages just can't be applied to D, which is a bothersome.
December 10, 2016
On 10.12.2016 09:09, Is it possible to store different generic types? wrote:
> I'm pretty sure the following code should work, but it doesn't.
>
> ```
> bool intersect(ptrdiff_t targetX, ptrdiff_t targetY, size_t targetWidth,
> size_t targetHeight, ptrdiff_t x, ptrdiff_t y, size_t width, size_t height)
> {
>  return targetX < x + width &&
>        x < targetX + targetWidth &&
>        targetY < y + height &&
>        y < targetY + targetHeight;
> }
>
> void main() {
>     import std.stdio;
>     writeln(intersect(0,0,800,600,     0,150,148,148));
>     writeln(intersect(0,0,800,600,     -10,150,148,148));
> }
> ```
>
> It outputs:
> ```
> true
> false
> ```
>
> On the contrary if you write the same piece of code in other languages
> ex. C#
> ...

Try to write it in C or C++.

> (Ran it through Linqpad)
> ```
> bool intersect(int targetX, int targetY, uint targetWidth, uint
> targetHeight, int x, int y, uint width, uint height)
> {
>  return targetX < x + width &&
>        x < targetX + targetWidth &&
>        targetY < y + height &&
>        y < targetY + targetHeight;
> }
>
> void Main() {
>     intersect(0,0,800,600,     0,150,148,148).Dump();
>     intersect(0,0,800,600,     -10,150,148,148).Dump();
> }
> ```
>
> Then it outputs:
> ```
> true
> true
> ```
>
> Is it a bug or is it intended behavior?
>
>

This is intended (but surprising, and IMHO bad) behaviour, as D follows C integral promotion rules. (C# does not.) Mixed signed/unsigned operations first convert both arguments to unsigned.
December 10, 2016
On Saturday, 10 December 2016 at 08:23:06 UTC, Ali Çehreli wrote:
> On 12/10/2016 12:16 AM, Is it possible to store different generic types? wrote:
>
> > Okay the issue seem to be that D casts the left-hand argument
> to the
> > same type as the right-hand argument.
>
> Seems to be but not true. It's more like "anything that touches an unsigned type turns unsigned". :)
>
>   https://dlang.org/spec/type.html#integer-promotions
>
> The more important topic there is the second one: "Usual Arithmetic Conversions"
>
> Ali

Thanks for that, at least I can see why.

3 If the signed type is larger than the unsigned type, the unsigned type is converted to the signed type.

4 The signed type is converted to the unsigned type.

It's obvious from the documentation that it's intended behavior as it obviously won't fall into the third category as ptrdiff_t and size_t are the same bit-size. Thus category 4 happens.
December 10, 2016
On 10.12.2016 09:24, Is it possible to store different generic types? wrote:
> On Saturday, 10 December 2016 at 08:21:17 UTC, Stefan Koch wrote:
>> On Saturday, 10 December 2016 at 08:16:48 UTC, Is it possible to store
>> different generic types? wrote:
>>> On Saturday, 10 December 2016 at 08:09:00 UTC, Is it possible to
>>> store different generic types? wrote:
>>>> [...]
>>> Okay the issue seem to be that D casts the left-hand argument to the
>>> same type as the right-hand argument.
>>>
>>> So when ex. doing "targetX < x + width" then it actually does
>>> "targetX < cast(width_type)x + width"
>>>
>>> Where as I'd believe the behavior should have been "targetX < x +
>>> cast(x_type)width"
>>
>> Simply don't mix signed and unsigned types.
>> That is begging for trouble.
>> or convert them to the next highter signed type.
>
> Yeah, that's what I'm doing now. It seems like concepts of casting from
> other languages just can't be applied to D,

From /some/ other languages, which is unavoidable, because different languages behave differently.

> which is a bothersome.


December 10, 2016
On Saturday, 10 December 2016 at 08:25:49 UTC, Timon Gehr wrote:
> On 10.12.2016 09:09, Is it possible to store different generic
>
> This is intended (but surprising, and IMHO bad) behaviour, as D follows C integral promotion rules. (C# does not.) Mixed signed/unsigned operations first convert both arguments to unsigned.

Yeah, it was a pain to figure out what was wrong. Been spending more time than I wanted tracking this down.