torek@elf.ee.lbl.gov (Chris Torek) (02/26/91)
(This is a topic for comp.lang.c, not comp.std.c; I have redirected followups there.) In article <1998@gold.gvg.tek.com> shaunc@gold.gvg.tek.com (Shaun Case) writes: >I know that when you repeatedly access something like > >foo.a.b.c.d[11].value > >it is better to declare a (register) pointer, assign it the address >of foo.a.b.c.d[11].value, and do manipulations on that, since it >is faster. This is an unsupported assertion, and in fact it often turns out to be no faster (though usually no slower either). In particular, given ... >a heavily nested structure ... >I want to access the various members of a.x.something (.foo, .foo2, >.blah, .blah2) quickly. ... structures that are nested in this manner (where variable `a' is a structure containing a member `x' which itself is a structure containing a member `something' which itself is a structure containing members `foo', `foo2', etc.) are typically implemented such that computing &a.x.something.foo requires exactly as much work as computing &a.x or &a.x.something. For instance, on the 68010, the difference between: a.x.something.foo = 3; and: local_var = 3; is, in essence, moveq #3,a5@260 and moveq #3,a7@-32 both of which require exactly the same amount of time and space. On the other hand, writing ptr->x.something.foo = 3; ptr->x.something.foo2 = 3 * 3; ptr->x.something.blah = "headache"; is generally perceived to be less clear than writing: s->foo = 3; s->foo2 = 3 * 3; s->blah = "headache"; and if you agree, you should use the latter. >I have a function that I pass a pointer to type struct a, thus: > >void do_stuff (struct *a ptr) >{} > >and what I want to do is something like > >register char *fastptr; > >fastptr = &(ptr->x.something) > >and then access fastptr->foo, fastptr->foo2, etc. It would help greatly if your examples were legal C.... To take the conceptual error first: Declaring `fastptr' as `register char *fastptr' means that `fastptr' points to `char's. It does not point to structures. Since it does not point to structures, you may not use it to obtain elements of structures. If you want a pointer to point to one or more structures of type `struct glorp', you must declare it as a pointer to `struct glorp': struct glorp *g; Next, if `ptr' is to point to a `struct a', the proper syntax is: void do_stuff(struct a *ptr) Composing these and adding the assignment to make `g' point to the glorp member of the structure to which `ptr' points, we get: void do_stuff(struct a *ptr) { struct glorp *g; g = &ptr->x.something; At this point you can use `g->foo', `g->foo2', and so on exactly as above. It will likely be no faster (but more readable and/or less cumbersome) than using `ptr->x.something.foo', etc. On the other hand, if `ptr' were to point to a structure in which the sub-structures are not directly imbedded, but rather found through pointers, then: void do_stuff(struct object *o) { struct value *v; /* * Pick up object's current value pointer, * which is found by reading its attributes * to find its current binding, and then * reading the binding to find the current value. */ v = o->o_attr->a_binding->b_value; ... } in this case using `v' is more likely (but still not guaranteed!) to be faster than writing `o->o_attr->a_binding->b_value' each time. It is also almost certain to make those editing the code happier. -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab EE div (+1 415 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov