Can anyone explain what's going on with this in m_pd.h:
typedef struct _scalar /* a graphical object holding data */ { t_gobj sc_gobj; /* header for graphical object */ t_symbol *sc_template; /* template name (LATER replace with pointer) */ t_word sc_vec[1]; /* indeterminate-length array of words */ } t_scalar;
How is a static t_word array of size 1 an indeterminate-length array? Is its placement as the last member of the struct required?
I see lots of mysterious casts in the internals of Pd's data structures. What's the trick here, and is it documented anywhere on the interwebs, a C standard doc, etc.?
Thanks, Jonathan
Hi all -
I don't know if this is a reasonable thing to do in 2014 - it's a coding trope I learned around 1981. As far as I know C has no clean way to describe a packed data structure with a header and then a variable number of identical elements (like a soundfile with a header followed by samples). In this case, the object consists of a structure,
t_gobj sc_gobj;
t_symbol *sc_template;
followed in memory by an array of t_words. One can't make a zero-size arary in standard C (as far as I know) and so it's declared as having the artificial size 1. If there are n elements, the size of the structure is
sizeof(t_scalar) + (n-1) * sizeof(t_word)
subtracting 1 for the one that stood in for the array.
cheers Miller
On Thu, Feb 20, 2014 at 06:32:48PM -0800, Jonathan Wilkes wrote:
Can anyone explain what's going on with this in m_pd.h:
typedef struct _scalar     /* a graphical object holding data */ {    t_gobj sc_gobj;        /* header for graphical object */    t_symbol *sc_template; /* template name (LATER replace with pointer) */    t_word sc_vec[1];      /* indeterminate-length array of words */ } t_scalar;
How is a static t_word array of size 1 an indeterminate-length array? Is its placement as the last member of the struct required?
I see lots of mysterious casts in the internals of Pd's data structures. What's the trick here, and is it documented anywhere on the interwebs, a C standard doc, etc.?
Thanks, Jonathan
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Hi,
Sorry for this question, but why isn't sc_vec a good old pointer ?
   t_gobj sc_gobj;        /* header for graphical object */    t_symbol *sc_template; /* template name (LATER replace with pointer) */    t_word sc_vec[1];      /* indeterminate-length array of words */ } t_scalar;
How is a static t_word array of size 1 an indeterminate-length array? Is its placement as the last member of the struct required?
Because this way you can reference data points with sc_vec+n as opposed to dealing with single or double linked lists (since sc_vec can be an array). On Feb 21, 2014 7:26 AM, "Charles Goyard" cg@fsck.fr wrote:
Hi,
Sorry for this question, but why isn't sc_vec a good old pointer ?
t_gobj sc_gobj; /* header for graphical object */ t_symbol *sc_template; /* template name (LATER replace with
pointer) */
t_word sc_vec[1]; /* indeterminate-length array of words */
} t_scalar;
How is a static t_word array of size 1 an indeterminate-length array?
Is its placement as the last member of the struct required?
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
On 02/21/2014 09:00 AM, Ivica Bukvic wrote:
Because this way you can reference data points with sc_vec+n as opposed to dealing with single or double linked lists (since sc_vec can be an array).
If sc_vec is a pointer then you can access data points using the same technique, which is pointer math after all.
For everyone's amusement, here's an exercise in my own rank speculation: something about a t_word array aligning on boundaries in a way that you wouldn't be able to guarantee with a pointer to a t_word. So if you can guarantee there won't be padding you save memory in 1981.
Is it something like that, Miller?
And do scalars actually go back to 1981, or that's just around the time you learned the technique?
Also-- this technique means that for sc_vec[1] its position inside the struct suddenly become relevant. That is, if you put sc_template as the last member field you'd be indexing into the wrong place when you tried to read/write sc_vec data. Is that right?
-Jonathan
On Feb 21, 2014 7:26 AM, "Charles Goyard" <cg@fsck.fr mailto:cg@fsck.fr> wrote:
Hi, Sorry for this question, but why isn't sc_vec a good old pointer ? > t_gobj sc_gobj; /* header for graphical object */ > t_symbol *sc_template; /* template name (LATER replace with pointer) */ > t_word sc_vec[1]; /* indeterminate-length array of words */ > } t_scalar; > > How is a static t_word array of size 1 an indeterminate-length array? Is its placement as the last member of the struct required? _______________________________________________ Pd-list@iem.at <mailto:Pd-list@iem.at> mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
It's more efficient (especially in terms of memory) to keep the two things contiguously in memory than to have to chase an additional pointer to the array. In C it looks almost the same (arrays and their pointers are both specified by naming the arraym but "sizeof" will act differently for instance.
And yes, the "growable" part of a structure has to be the last thing for it to work.
I learned how to do this in 1981 but scalars only go back to around 1997.
cheers M
On Fri, Feb 21, 2014 at 02:23:43PM -0500, Jonathan Wilkes wrote:
On 02/21/2014 09:00 AM, Ivica Bukvic wrote:
Because this way you can reference data points with sc_vec+n as opposed to dealing with single or double linked lists (since sc_vec can be an array).
If sc_vec is a pointer then you can access data points using the same technique, which is pointer math after all.
For everyone's amusement, here's an exercise in my own rank speculation: something about a t_word array aligning on boundaries in a way that you wouldn't be able to guarantee with a pointer to a t_word. So if you can guarantee there won't be padding you save memory in 1981.
Is it something like that, Miller?
And do scalars actually go back to 1981, or that's just around the time you learned the technique?
Also-- this technique means that for sc_vec[1] its position inside the struct suddenly become relevant. That is, if you put sc_template as the last member field you'd be indexing into the wrong place when you tried to read/write sc_vec data. Is that right?
-Jonathan
On Feb 21, 2014 7:26 AM, "Charles Goyard" <cg@fsck.fr mailto:cg@fsck.fr> wrote:
Hi,
Sorry for this question, but why isn't sc_vec a good old pointer ?
t_gobj sc_gobj; /* header for graphical object */ t_symbol *sc_template; /* template name (LATER replace with
pointer) */
t_word sc_vec[1]; /* indeterminate-length array of
words */
} t_scalar;
How is a static t_word array of size 1 an indeterminate-length
array? Is its placement as the last member of the struct required?
Pd-list@iem.at mailto:Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list
Pd-list@iem.at mailing list UNSUBSCRIBE and account-management -> http://lists.puredata.info/listinfo/pd-list