Hi list, int compare_pointers(t_pd *foo){ long bar = generate_random_long(); return (((void *)foo) == ((void *)bar));} (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the sameundefined behavior? -Jonathan
As I understand it, you can compare void pointers because they just store addresses.
In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object) { t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0); }
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list < pd-list@lists.iem.at> wrote:
Hi list,
int compare_pointers(t_pd *foo) { long bar = generate_random_long(); return (((void *)foo) == ((void *)bar)); }
(I probably have unnecessary parens there...)
Is the check for equality a case of undefined behavior?
If so, doesn't glob_findinstance of s_print.c also lead to the same undefined behavior?
-Jonathan
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
But if you trace error_object back, you'll see it gets created from an sscanfof a c string. And that string was stored in the tcl/tk "text" widget as state boundto a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a"hyperlink"). That state can persist well past the life of the object it referred to. For example,the error_object could have been deleted by the user. That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libctechnically allowed to respond by serving Pd users a listicle of the top 10 Cprogramming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
As I understand it, you can compare void pointers because they just store addresses. In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object){ t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0);}
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list pd-list@lists.iem.at wrote:
Hi list, int compare_pointers(t_pd *foo){ long bar = generate_random_long(); return (((void *)foo) == ((void *)bar));} (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the sameundefined behavior? -Jonathan _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation.
On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanf of a c string. And that string was stored in the tcl/tk "text" widget as state bound to a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a "hyperlink").
That state can persist well past the life of the object it referred to. For example, the error_object could have been deleted by the user.
That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libc technically allowed to respond by serving Pd users a listicle of the top 10 C programming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber brbrofsvl@gmail.com wrote:
As I understand it, you can compare void pointers because they just store addresses.
In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object) { t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0); }
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list < pd-list@lists.iem.at> wrote:
Hi list,
int compare_pointers(t_pd *foo) { long bar = generate_random_long(); return (((void *)foo) == ((void *)bar)); }
(I probably have unnecessary parens there...)
Is the check for equality a case of undefined behavior?
If so, doesn't glob_findinstance of s_print.c also lead to the same undefined behavior?
-Jonathan
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Well, two questions I guess:1) false positives-- if I deleted [float] and create [clip], can't malloc use the addythat belonged to [float]? In that case [clip] could get associated with an errorit had nothing to do with.2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it...3) is there a way to create something like [readpd~] which would take indicesas input and output the corresponding bytes of the running Pd instance? :) -Jonathan
On Thursday, October 1, 2015 11:22 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation. On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanfof a c string. And that string was stored in the tcl/tk "text" widget as state boundto a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a"hyperlink"). That state can persist well past the life of the object it referred to. For example,the error_object could have been deleted by the user. That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libctechnically allowed to respond by serving Pd users a listicle of the top 10 Cprogramming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
As I understand it, you can compare void pointers because they just store addresses. In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object){ t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0);}
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list pd-list@lists.iem.at wrote:
Hi list, int compare_pointers(t_pd *foo){ long bar = generate_random_long(); return (((void *)foo) == ((void *)bar));} (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the sameundefined behavior? -Jonathan _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
So, if you deleted [float] and created [clip], isn't it going to bash whatever c string was associated with [float] and associate it with [clip]? Moreover, that kind of error has to occur in an object that exists in the current state (I think?), so the old [float] (once it's gone) could never be part of an error in the first place.
For 2) I think it depends on what you're going to do with the void pointer(s). Your compare_pointers() function could actually be read as the meat of a "guess my address!" roulette game. If you decided to write to *bar in case it matched, it might be a "guess my address!" Russian roulette game. I'm not sure what the compiler would say about that since I think you'd have to cast *bar back to something you could write.
On Thu, Oct 1, 2015 at 11:57 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
Well, two questions I guess:
- false positives-- if I deleted [float] and create [clip], can't malloc
use the addy that belonged to [float]? In that case [clip] could get associated with an error it had nothing to do with. 2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it... 3) is there a way to create something like [readpd~] which would take indices as input and output the corresponding bytes of the running Pd instance? :)
-Jonathan
On Thursday, October 1, 2015 11:22 PM, Matt Barber brbrofsvl@gmail.com wrote:
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation.
On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanf of a c string. And that string was stored in the tcl/tk "text" widget as state bound to a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a "hyperlink").
That state can persist well past the life of the object it referred to. For example, the error_object could have been deleted by the user.
That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libc technically allowed to respond by serving Pd users a listicle of the top 10 C programming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber brbrofsvl@gmail.com wrote:
As I understand it, you can compare void pointers because they just store addresses.
In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object) { t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0); }
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list < pd-list@lists.iem.at> wrote:
Hi list,
int compare_pointers(t_pd *foo) { long bar = generate_random_long(); return (((void *)foo) == ((void *)bar)); }
(I probably have unnecessary parens there...)
Is the check for equality a case of undefined behavior?
If so, doesn't glob_findinstance of s_print.c also lead to the same undefined behavior?
-Jonathan
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
For the first question, here's what I'm thinking:1) create [boat(---[float]2) click [boat(3) error associated with [float]. (string ".x1234567" associated with [float] gets saved in Pd window of GUI)4) delete [float]5) create [clip]6) somehow the OS happens to use addy "1234567" for [clip] 7) click the error in the Pd window 8) GUI sends "pd findinstance .x1234567" to Pd9) Pd assigns "1234567" to error_object10) Pd compares [clip] object's "1234567" to old [float] addy "1234567"11) It's a match!12) [clip] is falsely accused For #2-- I guess I'm just anxious since most of the docs I've read assumea void* is either NULL or pointing to something that exists. -Jonathan
On Friday, October 2, 2015 12:15 AM, Matt Barber <brbrofsvl@gmail.com> wrote:
So, if you deleted [float] and created [clip], isn't it going to bash whatever c string was associated with [float] and associate it with [clip]? Moreover, that kind of error has to occur in an object that exists in the current state (I think?), so the old [float] (once it's gone) could never be part of an error in the first place. For 2) I think it depends on what you're going to do with the void pointer(s). Your compare_pointers() function could actually be read as the meat of a "guess my address!" roulette game. If you decided to write to *bar in case it matched, it might be a "guess my address!" Russian roulette game. I'm not sure what the compiler would say about that since I think you'd have to cast *bar back to something you could write.
On Thu, Oct 1, 2015 at 11:57 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
Well, two questions I guess:1) false positives-- if I deleted [float] and create [clip], can't malloc use the addythat belonged to [float]? In that case [clip] could get associated with an errorit had nothing to do with.2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it...3) is there a way to create something like [readpd~] which would take indicesas input and output the corresponding bytes of the running Pd instance? :) -Jonathan
On Thursday, October 1, 2015 11:22 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation. On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanfof a c string. And that string was stored in the tcl/tk "text" widget as state boundto a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a"hyperlink"). That state can persist well past the life of the object it referred to. For example,the error_object could have been deleted by the user. That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libctechnically allowed to respond by serving Pd users a listicle of the top 10 Cprogramming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
As I understand it, you can compare void pointers because they just store addresses. In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object){ t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0);}
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list pd-list@lists.iem.at wrote:
Hi list, int compare_pointers(t_pd *foo){ long bar = generate_random_long(); return (((void *)foo) == ((void *)bar));} (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the sameundefined behavior? -Jonathan _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Most of the docs also don't expect you run a pointer out of the bounds of an array, either, but the compiler trusts you know what you're doing.
I see what you mean in the first question. Can we make a patch to test it dynamically?
On Fri, Oct 2, 2015 at 12:36 AM, Jonathan Wilkes jancsika@yahoo.com wrote:
For the first question, here's what I'm thinking:
- create [boat(---[float]
- click [boat(
- error associated with [float]. (string ".x1234567" associated with
[float] gets saved in Pd window of GUI) 4) delete [float] 5) create [clip] 6) somehow the OS happens to use addy "1234567" for [clip] 7) click the error in the Pd window 8) GUI sends "pd findinstance .x1234567" to Pd 9) Pd assigns "1234567" to error_object 10) Pd compares [clip] object's "1234567" to old [float] addy "1234567" 11) It's a match! 12) [clip] is falsely accused
For #2-- I guess I'm just anxious since most of the docs I've read assume a void* is either NULL or pointing to something that exists.
-Jonathan
On Friday, October 2, 2015 12:15 AM, Matt Barber brbrofsvl@gmail.com wrote:
So, if you deleted [float] and created [clip], isn't it going to bash whatever c string was associated with [float] and associate it with [clip]? Moreover, that kind of error has to occur in an object that exists in the current state (I think?), so the old [float] (once it's gone) could never be part of an error in the first place.
For 2) I think it depends on what you're going to do with the void pointer(s). Your compare_pointers() function could actually be read as the meat of a "guess my address!" roulette game. If you decided to write to *bar in case it matched, it might be a "guess my address!" Russian roulette game. I'm not sure what the compiler would say about that since I think you'd have to cast *bar back to something you could write.
On Thu, Oct 1, 2015 at 11:57 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
Well, two questions I guess:
- false positives-- if I deleted [float] and create [clip], can't malloc
use the addy that belonged to [float]? In that case [clip] could get associated with an error it had nothing to do with. 2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it... 3) is there a way to create something like [readpd~] which would take indices as input and output the corresponding bytes of the running Pd instance? :)
-Jonathan
On Thursday, October 1, 2015 11:22 PM, Matt Barber brbrofsvl@gmail.com wrote:
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation.
On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanf of a c string. And that string was stored in the tcl/tk "text" widget as state bound to a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a "hyperlink").
That state can persist well past the life of the object it referred to. For example, the error_object could have been deleted by the user.
That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libc technically allowed to respond by serving Pd users a listicle of the top 10 C programming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber brbrofsvl@gmail.com wrote:
As I understand it, you can compare void pointers because they just store addresses.
In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object) { t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0); }
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list < pd-list@lists.iem.at> wrote:
Hi list,
int compare_pointers(t_pd *foo) { long bar = generate_random_long(); return (((void *)foo) == ((void *)bar)); }
(I probably have unnecessary parens there...)
Is the check for equality a case of undefined behavior?
If so, doesn't glob_findinstance of s_print.c also lead to the same undefined behavior?
-Jonathan
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
I do have [objectinfo] inside Pd-l2ork. But I don't have a method toreturn the memory location of the object. I also have a "find" method in [canvasinfo] which is very handy-- but it searches based on the box text. I could add an obscure"find_by_memory_location" method which would do the trick. Then it'd just be a matter of:1) generate error for some object2) note the object's address3) delete the object4) dynamically create new obj in subpatch 5) check if that new object's address matches old object address6) if not, clear the subpatch7) repeat until you find a match -Jonathan
On Friday, October 2, 2015 1:05 AM, Matt Barber <brbrofsvl@gmail.com> wrote:
Most of the docs also don't expect you run a pointer out of the bounds of an array, either, but the compiler trusts you know what you're doing. I see what you mean in the first question. Can we make a patch to test it dynamically? On Fri, Oct 2, 2015 at 12:36 AM, Jonathan Wilkes jancsika@yahoo.com wrote:
For the first question, here's what I'm thinking:1) create [boat(---[float]2) click [boat(3) error associated with [float]. (string ".x1234567" associated with [float] gets saved in Pd window of GUI)4) delete [float]5) create [clip]6) somehow the OS happens to use addy "1234567" for [clip] 7) click the error in the Pd window 8) GUI sends "pd findinstance .x1234567" to Pd9) Pd assigns "1234567" to error_object10) Pd compares [clip] object's "1234567" to old [float] addy "1234567"11) It's a match!12) [clip] is falsely accused For #2-- I guess I'm just anxious since most of the docs I've read assumea void* is either NULL or pointing to something that exists. -Jonathan
On Friday, October 2, 2015 12:15 AM, Matt Barber <brbrofsvl@gmail.com> wrote:
So, if you deleted [float] and created [clip], isn't it going to bash whatever c string was associated with [float] and associate it with [clip]? Moreover, that kind of error has to occur in an object that exists in the current state (I think?), so the old [float] (once it's gone) could never be part of an error in the first place. For 2) I think it depends on what you're going to do with the void pointer(s). Your compare_pointers() function could actually be read as the meat of a "guess my address!" roulette game. If you decided to write to *bar in case it matched, it might be a "guess my address!" Russian roulette game. I'm not sure what the compiler would say about that since I think you'd have to cast *bar back to something you could write.
On Thu, Oct 1, 2015 at 11:57 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
Well, two questions I guess:1) false positives-- if I deleted [float] and create [clip], can't malloc use the addythat belonged to [float]? In that case [clip] could get associated with an errorit had nothing to do with.2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it...3) is there a way to create something like [readpd~] which would take indicesas input and output the corresponding bytes of the running Pd instance? :) -Jonathan
On Thursday, October 1, 2015 11:22 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation. On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes jancsika@yahoo.com wrote:
But if you trace error_object back, you'll see it gets created from an sscanfof a c string. And that string was stored in the tcl/tk "text" widget as state boundto a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a"hyperlink"). That state can persist well past the life of the object it referred to. For example,the error_object could have been deleted by the user. That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libctechnically allowed to respond by serving Pd users a listicle of the top 10 Cprogramming references available from Amazon with free shipping?
-Jonathan
On Thursday, October 1, 2015 7:32 PM, Matt Barber <brbrofsvl@gmail.com> wrote:
As I understand it, you can compare void pointers because they just store addresses. In g_editor.c:
static int glist_dofinderror(t_glist *gl, void *error_object){ t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0);}
this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object.
On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list pd-list@lists.iem.at wrote:
Hi list, int compare_pointers(t_pd *foo){ long bar = generate_random_long(); return (((void *)foo) == ((void *)bar));} (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the sameundefined behavior? -Jonathan _______________________________________________ Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Is there a point of having more than one objectinfo at any point in time?
If not, you could have a static reference to that one objectinfo, or possibly have it instantiated in the background as an object that it associated with each canvas (or one per pd instance) and use the visual [objectinfo] as a mere proxy that forwards stuff to the invisible object (which means as a courtesy you could have multiple instances of [objectinfo] without any issues).
On 10/2/2015 11:50 AM, Jonathan Wilkes via Pd-list wrote:
I do have [objectinfo] inside Pd-l2ork. But I don't have a method to return the memory location of the object.
I also have a "find" method in [canvasinfo] which is very handy-- but it searches based on the box text. I could add an obscure "find_by_memory_location" method which would do the trick. Then it'd just be a matter of:
- generate error for some object
- note the object's address
- delete the object
I wonder if there is a more graceful way of doing this. If not, you could accompany object's address with its atomic creation time (which would require adding a member to a struct as long as it is internal to pd and not readily instantiated/accessible in 3rd-party externals) and that way compare whether it is the same object...
- dynamically create new obj in subpatch
- check if that new object's address matches old object address
- if not, clear the subpatch
- repeat until you find a match
-Jonathan
On Friday, October 2, 2015 1:05 AM, Matt Barber brbrofsvl@gmail.com wrote:
Most of the docs also don't expect you run a pointer out of the bounds of an array, either, but the compiler trusts you know what you're doing.
I see what you mean in the first question. Can we make a patch to test it dynamically?
On Fri, Oct 2, 2015 at 12:36 AM, Jonathan Wilkes <jancsika@yahoo.com mailto:jancsika@yahoo.com> wrote:
For the first question, here's what I'm thinking: 1) create [boat(---[float] 2) click [boat( 3) error associated with [float]. (string ".x1234567" associated with [float] gets saved in Pd window of GUI) 4) delete [float] 5) create [clip] 6) somehow the OS happens to use addy "1234567" for [clip] 7) click the error in the Pd window 8) GUI sends "pd findinstance .x1234567" to Pd 9) Pd assigns "1234567" to error_object 10) Pd compares [clip] object's "1234567" to old [float] addy "1234567" 11) It's a match! 12) [clip] is falsely accused For #2-- I guess I'm just anxious since most of the docs I've read assume a void* is either NULL or pointing to something that exists. -Jonathan On Friday, October 2, 2015 12:15 AM, Matt Barber <brbrofsvl@gmail.com <mailto:brbrofsvl@gmail.com>> wrote: So, if you deleted [float] and created [clip], isn't it going to bash whatever c string was associated with [float] and associate it with [clip]? Moreover, that kind of error has to occur in an object that exists in the current state (I think?), so the old [float] (once it's gone) could never be part of an error in the first place. For 2) I think it depends on what you're going to do with the void pointer(s). Your compare_pointers() function could actually be read as the meat of a "guess my address!" roulette game. If you decided to write to *bar in case it matched, it might be a "guess my address!" Russian roulette game. I'm not sure what the compiler would say about that since I think you'd have to cast *bar back to something you could write. On Thu, Oct 1, 2015 at 11:57 PM, Jonathan Wilkes <jancsika@yahoo.com <mailto:jancsika@yahoo.com>> wrote: Well, two questions I guess: 1) false positives-- if I deleted [float] and create [clip], can't malloc use the addy that belonged to [float]? In that case [clip] could get associated with an error it had nothing to do with. 2) Is it undefined behavior to check void* garbage for equality? And just for the heck of it... 3) is there a way to create something like [readpd~] which would take indices as input and output the corresponding bytes of the running Pd instance? :) -Jonathan On Thursday, October 1, 2015 11:22 PM, Matt Barber <brbrofsvl@gmail.com <mailto:brbrofsvl@gmail.com>> wrote: The left side is still determined by the current state of the patch, though -- it's only going to check objects that are still there, which any garbage on the right won't ever match (right?). If there is a match, it's going to be because the state on both sides of the == was updated when the object was created. We never really have to worry about false positives, so I'm not sure the random long is the same situation. On Thu, Oct 1, 2015 at 9:54 PM, Jonathan Wilkes <jancsika@yahoo.com <mailto:jancsika@yahoo.com>> wrote: But if you trace error_object back, you'll see it gets created from an sscanf of a c string. And that string was stored in the tcl/tk "text" widget as state bound to a <ctrl-click> proc (or in post-1980s version of Pd that I work on, a "hyperlink"). That state can persist well past the life of the object it referred to. For example, the error_object could have been deleted by the user. That's why I was generating a random long in my contrived example. If we cast garbage to void* and put it to the right of the equals sign, isn't libc technically allowed to respond by serving Pd users a listicle of the top 10 C programming references available from Amazon with free shipping? -Jonathan On Thursday, October 1, 2015 7:32 PM, Matt Barber <brbrofsvl@gmail.com <mailto:brbrofsvl@gmail.com>> wrote: As I understand it, you can compare void pointers because they just store addresses. In g_editor.c: static int glist_dofinderror(t_glist *gl, void *error_object) { t_gobj *g; for (g = gl->gl_list; g; g = g->g_next) { if ((void *)g == error_object) { /* got it... now show it. */ glist_noselect(gl); canvas_vis(glist_getcanvas(gl), 1); canvas_editmode(glist_getcanvas(gl), 1.); glist_select(gl, g); return (1); } else if (g->g_pd == canvas_class) { if (glist_dofinderror((t_canvas *)g, error_object)) return (1); } } return (0); } this function takes a pointer to void (storing the address of an object) as its second argument void *error_object. It can't know what the type of that object is, because it's being called from somewhere else, and it could be any kind of Pd object. That somewhere else knows what kind of object it is and (more importantly) where that object's address is, and just passes that address in. Then t_gobj *g; traverses the canvas, and since the address of each object is known, each of those can be compared to the object address passed in until there's a match. This is kind of a way of getting around the usual strong typing in c; as long as we know from both ends of the transaction that we can get valid addresses of what we're interested in, there's no problem just comparing those addresses to see if we've found the same object. On Thu, Oct 1, 2015 at 4:45 PM, Jonathan Wilkes via Pd-list <pd-list@lists.iem.at <mailto:pd-list@lists.iem.at>> wrote: Hi list, int compare_pointers(t_pd *foo) { long bar = generate_random_long(); return (((void *)foo) == ((void *)bar)); } (I probably have unnecessary parens there...) Is the check for equality a case of undefined behavior? If so, doesn't glob_findinstance of s_print.c also lead to the same undefined behavior? -Jonathan _______________________________________________ Pd-list@lists.iem.at <mailto:Pd-list@lists.iem.at> mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list