www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Is this a compiler aliasing bug?

reply Chris Katko <ckatko gmail.com> writes:
I'm debugging some code I wrote back in 2017 and a bounding box 
collision detection kept giving spurious answers till I resorted 
to assuming nothing and dumped every variable and alias.

I kept getting results like it was checking against itself, and 
of course, that would result in finding a collision. So I threw 
an assert in to check if it was identical objects (as in an error 
outside this function), and it didn't fire off. It appears 
(unless my eyes are deceiving me?) that variable aliases 
themselves are broken.

$ dmd --version
DMD64 D Compiler v2.098.0-beta.2

code:

```d
class drawable_object_t obj;

bool is_colliding_with(drawable_object_t obj) //was a class member
	{
	assert(this != obj);  //does not fire off

	alias x1 = x;
	alias y1 = y;
	alias w1 = w;
	alias h1 = h;
		
	alias x2 = obj.x;
	alias y2 = obj.y;
	alias w2 = obj.w;
	alias h2 = obj.h;
		
	writeln("x1: ", x1, " y1: ", y1, " w1: ", w1, " h1: ", h1);
	writeln("x2: ", x2, " y2: ", y2, " w2: ", w2, " h2: ", h2);

	writeln("x1: ", x, " y1: ", y, " w1: ", w, " h1: ", h);
	writeln("x2: ", obj.x, " y2: ", obj.y, " w2: ", obj.w, " h2: ", 
obj.h);
         }
/*
output:

x1: 50 y1: 81 w1: 5 h1: 6
x2: 50 y2: 81 w2: 5 h2: 6		<------------
x1: 50 y1: 81 w1: 5 h1: 6
x2: 200 y2: 86.54 w2: 26 h2: 16		<------------
*/
```

The arrows point to the dependency. The top two sets of numbers 
should _not_ be identical.
Sep 17 2021
next sibling parent ag0aep6g <anonymous example.com> writes:
On 17.09.21 11:44, Chris Katko wrote:
 bool is_colliding_with(drawable_object_t obj) //was a class member
      {
[...]
      alias x2 = obj.x;
      alias y2 = obj.y;
      alias w2 = obj.w;
      alias h2 = obj.h;
[...]
          }
Those aliases don't work like you want them to. You can't have an alias to an object's field. What you get is an alias to the symbol in the class. I.e., you get this: alias x2 = typeof(obj).x; And when you use that in a method, it becomes `this.x`. `obj` is completely forgotten. I my opinion, `alias x2 = obj.x` should be an error, but I'm not sure if it's considered a bug.
Sep 17 2021
prev sibling parent reply bauss <jj_1337 live.dk> writes:
On Friday, 17 September 2021 at 09:44:53 UTC, Chris Katko wrote:
 I'm debugging some code I wrote back in 2017 and a bounding box 
 collision detection kept giving spurious answers till I 
 resorted to assuming nothing and dumped every variable and 
 alias.

 I kept getting results like it was checking against itself, and 
 of course, that would result in finding a collision. So I threw 
 an assert in to check if it was identical objects (as in an 
 error outside this function), and it didn't fire off. It 
 appears (unless my eyes are deceiving me?) that variable 
 aliases themselves are broken.

 $ dmd --version
 DMD64 D Compiler v2.098.0-beta.2

 code:

 ```d
 class drawable_object_t obj;

 bool is_colliding_with(drawable_object_t obj) //was a class 
 member
 	{
 	assert(this != obj);  //does not fire off

 	alias x1 = x;
 	alias y1 = y;
 	alias w1 = w;
 	alias h1 = h;
 		
 	alias x2 = obj.x;
 	alias y2 = obj.y;
 	alias w2 = obj.w;
 	alias h2 = obj.h;
 		
 	writeln("x1: ", x1, " y1: ", y1, " w1: ", w1, " h1: ", h1);
 	writeln("x2: ", x2, " y2: ", y2, " w2: ", w2, " h2: ", h2);

 	writeln("x1: ", x, " y1: ", y, " w1: ", w, " h1: ", h);
 	writeln("x2: ", obj.x, " y2: ", obj.y, " w2: ", obj.w, " h2: 
 ", obj.h);
         }
 /*
 output:

 x1: 50 y1: 81 w1: 5 h1: 6
 x2: 50 y2: 81 w2: 5 h2: 6		<------------
 x1: 50 y1: 81 w1: 5 h1: 6
 x2: 200 y2: 86.54 w2: 26 h2: 16		<------------
 */
 ```

 The arrows point to the dependency. The top two sets of numbers 
 should _not_ be identical.
It's not a bug because "obj.x" referes to the same symbol that is "this.x" Alias will create an alias for a symbol, not an expression or the like. So obj.x is the same as this.x and in that case the alias will refer to the same thing. The problem here is that the function is local to the class, so the alias will always refer to the class members directly and not the passed instance. You really shouldn't use alias like this anyway and should just use auto, if it's because you want to save typing. It shouldn't have any impact at all tbh.
Sep 17 2021
parent Chris Katko <ckatko gmail.com> writes:
On Friday, 17 September 2021 at 10:29:12 UTC, bauss wrote:
 On Friday, 17 September 2021 at 09:44:53 UTC, Chris Katko wrote:
 [...]
It's not a bug because "obj.x" referes to the same symbol that is "this.x" Alias will create an alias for a symbol, not an expression or the like. So obj.x is the same as this.x and in that case the alias will refer to the same thing. The problem here is that the function is local to the class, so the alias will always refer to the class members directly and not the passed instance. You really shouldn't use alias like this anyway and should just use auto, if it's because you want to save typing. It shouldn't have any impact at all tbh.
Thanks everyone! Okay, so yeah, back in 2017 I definitely was still learning D. And, after a year or two, I was re-learning it... using this bad learner codebase! There's been plenty of other things I had to fix that are "no-nos" in my modern codebases.
Sep 22 2021