www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is this a bug?

reply Is it possible to store different generic types? <jj_1337 live.dk> writes:
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?
Dec 10 2016
next sibling parent reply Is it possible to store different generic types? <jj_1337 live.dk> writes:
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"
Dec 10 2016
next sibling parent reply Stefan Koch <uplink.coder googlemail.com> writes:
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.
Dec 10 2016
parent reply Is it possible to store different generic types? <jj_1337 live.dk> writes:
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.
Dec 10 2016
parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Dec 10 2016
prev sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
Dec 10 2016
parent Is it possible to store different generic types? <jj_1337 live.dk> writes:
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.
Dec 10 2016
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
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.
Dec 10 2016
parent bauss (wtf happend to my name took some old cached title LOL??) writes:
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.
Dec 10 2016