Re: What's wrong with this code?

2015-09-19 Thread Chris via Digitalmars-d-learn
On Saturday, 19 September 2015 at 02:45:54 UTC, Adam D. Ruppe 
wrote:

On Saturday, 19 September 2015 at 02:30:39 UTC, Chris wrote:

bmove.addOnClicked (delegate void (Button aux) {


What's the context of this call? If it is inside a struct and 
you are accessing local variables you can get in trouble 
because the context pointer may not be correct. You are using 
`vec` there, if `glw` is a struct/class member too, then the 
compiler can sometimes be a bit stupid about bringing in the 
correct `this` reference to the delegate.


Hi thanks for the response.

The context is inside a try block in the program's main() 
function. Glw is indeed a class but it doesn't look like it quite 
configures the problem you describe.


I think #3 will work for you here. Right above that loop, try 
something like


auto glw = this.glw;


There's no "this", it's the main() function. I stuck a "auto glw2 
= glw" in there but it didn't help.


I found more funny stuff. If I move the code around and change 
the order of that snippet to before the other one I posted 
earlier, the first line (if (!glw...) now works *despite* the 
debugger saying the variable glw is "not found". So now as long 
as the condition evaluates to true it will work as expected. 
However when the condition is made to eval to false then the 
*next* line of code will trigger the exception as I first 
encountered.


So I'm going to go ahead and say I found a compiler bug.


Re: What's wrong with this code?

2015-09-19 Thread Chris via Digitalmars-d-learn

Update:

If I add *also* a auto vec2 = vec; now the code works. So it 
looks like this now:


voxel_vec [string] move_buttons = [
"button_xp" : voxel_vec ([ 1, 0, 0 ]),
"button_xm" : voxel_vec ([ -1, 0, 0 ]),
"button_yp" : voxel_vec ([ 0, 1, 0 ]),
"button_ym" : voxel_vec ([ 0, -1, 0 ]),
"button_zp" : voxel_vec ([ 0, 0, 1 ]),
"button_zm" : voxel_vec ([ 0, 0, -1 ]) ];

foreach (bname, vec; move_buttons) {
Button bmove = cast (Button) g.getObject (bname);

bmove.addOnClicked (delegate void (Button aux) {
auto glw2 = glw;
auto vec2 = vec;

if (!glw2.sel_active) return;

glw2.vf.move (3, vec2, glw2.sel_limits);
glw2.set_mesh (glw2.vf.polygonize);
} );
}

and works as expected. I'm going to leave it like that in the 
belief it's a compiler bug, if someone wants to take a look at 
the full source I'm willing to disclose it.


Thanks again for the help and the idea of the work around.


Re: What's wrong with this code?

2015-09-18 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 19 September 2015 at 02:30:39 UTC, Chris wrote:

bmove.addOnClicked (delegate void (Button aux) {


What's the context of this call? If it is inside a struct and you 
are accessing local variables you can get in trouble because the 
context pointer may not be correct. You are using `vec` there, if 
`glw` is a struct/class member too, then the compiler can 
sometimes be a bit stupid about bringing in the correct `this` 
reference to the delegate.


Basically the problem is that a delegate only has one pointer 
inside to the data it needs. Usually, it points to the this for 
an object OR to a copy of the local variables. But since you want 
to access members of both, it is too stupid to handle that case 
and tries to access like this.glw through the local variable 
copy... where this and thus glw don't actually exist, which is 
why the debugger is saying what it is saying.


I've seen this before (and even briefly mentioned it in my dconf 
talk this year) and found three possible workaround solutions:


1) make some parts struct static. Probably not applicable to 
you...


2) use a temporary delegate to which you pass arguments 
explicitly, to make a copy of them in one spot


3) or, in a similar vein, make a local copy of the this variable 
or references you need and access parts through it.



I think #3 will work for you here. Right above that loop, try 
something like


auto glw = this.glw;


or something, maybe you will want to change names so it isn't as 
ambiguous.


But give that a try and run it again, I betcha you'll find some 
success.




b.addOnValueChanged (delegate void (SpinButton aux) {
for (int i = 0; i < 6; i++)
sellimits [i] = selwidgets [i].getValueAsInt ();

glw.set_sel_box (sellimits);
glw.sel_active = 1;
glw.actual_queue_draw ();
});


See, here, you're just using glw, no local variables, to if it 
pulls the struct/class `this` as the delegate pointer, you'll be 
in business. That's why I suspect this is the issue.



Could this be a compiler bug?


arguably, it should at least not compile and do the wrong thing.


Re: What's wrong with this code?

2011-01-10 Thread Steven Schveighoffer
On Sat, 08 Jan 2011 15:46:01 -0500, Michal Minich  
michal.min...@gmail.com wrote:



On Sat, 08 Jan 2011 20:34:39 +, Sean Eskapp wrote:


if(left == null)


1) write if (left is null) instead if checking for null. Equality
operator is rewritten to a.opEquals(b), which you don't want if you
checking for null.


Actually, this is no longer true.  For comparing two classes or  
interfaces, a == b becomes .opEquals(a, b)  which is defined in object.di  
and properly handles null references.


However, if checking for null, a is null is going to be more correct and  
as efficient as possible (a == b should be inlined to the same thing, but  
only if you have inlining enabled).


-Steve


Re: What's wrong with this code?

2011-01-08 Thread Michal Minich
On Sat, 08 Jan 2011 20:34:39 +, Sean Eskapp wrote:

   if(left == null)

1) write if (left is null) instead if checking for null. Equality 
operator is rewritten to a.opEquals(b), which you don't want if you 
checking for null.

 this()
 {
 left = right = null;
 }
2) default constructor as you written it is not needed, fields are always 
initialized to default value of their type, which is in this case null.

 private const Fib* left, right;
3) Classes in D are reference types. It should be 
 private const Fib left, right;

4) second constructor - Classes in D are reference types,  operator is 
not needed (see point 3), parameter left and right are already references 
to class.


Re: What's wrong with this code?

2011-01-08 Thread Tomek Sowiński

Sean Eskapp napisał(a):


I had some code that was segfaulting, so I rewrote the basic idea as a
fibonacci function, and lo and behold, it still segfaults. Why, and how  
to fix?


This looks fishy:

class Fib
{
private const Fib* left, right;
...
this(in Fib left, in Fib right)
{
this.left = left;
this.right = right;
}


Are you sure you want a pointer to class? Classes have reference semantics  
in D (like Java). Structs are value types, though. Anyway, it looks like  
the ctor takes the address of the reference placed on the stack.


--
Tomek


Re: What's wrong with this code? (OP)

2011-01-08 Thread Sean Eskapp
Tomek got it right. Fixed by copying the objects, rather than using pointers. 
Thanks!