do ptrs to struct members make code more compact than simple member access?

I have a fairly large program on a NANO, where more and more variables are being added to a global structure. This allows me to quickly save the whole struct when I detect eminent power loss, and easily recover and resume next time I run. Until now, I've referenced most oif my struct members with a member access operator (struct.member). But as the code is growing, I'm wondering if it would pay to make a global pointer to the structure, and get/set all items with member access operators (pTstruct->member). Would it shrink the program or make it run faster?

I seem to remember working in ordinary vanilla 'C' on Intel 386 code with a Microsoft compiler, where making this change shrunk programs code space significantly. But would it make a hill of beans difference on this platform?

Using pointers will save some time (not copying the struct onto the stack) and save stack (not copying the struct onto the stack). It will make your program code shorter in that you will no longer incur the overhead of the copy instructions (MOV). Depending on how many places within your code you reference the struct, this impact may be negligible. Using pointers to struct are more effective when you have multiple struct that can all be serviced by the same function and can then pass the struct by reference.

As an example, create a typedef struct to include a buffer, first and next indexes. You can now make multiple buffers using that typedef and service them all with two functions such as putch and getch, passing the reference to the typedef’d buffer. This is a typical implementation of multiple ring (FIFO) buffers.

Is your large struct global / static?

DKWatson:
Depending on how many places within your code you reference the struct, this impact may be negligible. Using pointers to struct are more effective when you have multiple struct that can all be serviced by the same function and can then pass the struct by reference.

The struct is getting fairly large with ordinary variables. No buffers as you described, but lots of configured timer limits along with current timers in progress, and quite a few state flags and variables. The members are all referenced frequently within the code. In fact, since the process is time based (there is an RTC), I'm quite often adding flags to the structure to make sure time-of-day sensitive processes are compensated for if the power is lost for many hours.( Obviously the more information is preserved through a power fail, the less convoluted code is needed to "figure out" where I am, so to speak.) But this is all adding up to a lot of global structure member access within loop(). So maybe a global pointer would ease the stack requirements, and maybe make the code compile a little smaller too?

Yes.

Then the cost of accessing individual members is exactly the same as the cost of accessing the same datatype as a simple global. Which is the second most efficient way to access data (the first being data stored in registers).

Introducing a pointer buys you nothing and consumes more of everything.

If the struct is global and you are referencing it within your functions rather that passing a copy of it, you're not going to realize any weight reduction as the references will all be converted to memory locations during compile and there will only ever be one copy of it in SRAM. The way that branches/jumps work at the machine level will always favor local variables over global in terms of speed, sometimes 2:1. This is offset of course by memory requirements - always a tradeoff. You have to decide which is more important.

OK thanks everyone! Very helpful. Yes, the structure must be static/global to the whole program, and 90% of accesses to its members is calling upon that global struct by name. So if there's nothing to be gained by adding a global pointer to it, I'll leave well enough alone.

Always a strategy.

Accessing a structure via pointers can be somewhat more compact, because an “ld r1, y+n” is a two byte instruction, while “lds r1, adr” is a 4 byte instruction. But “n” is limited to rather small numbers, and there are only two index registers that can be used, so you are not likely to see an improvement with a large structure over a large program.

westfw:
Accessing a structure via pointers can be somewhat more compact, because an “ld r1, y+n” is a two byte instruction, while “lds r1, adr” is a 4 byte instruction. But “n” is limited to rather small numbers, and there are only two index registers that can be used, so you are not likely to see an improvement with a large structure over a large program.

Hmmm... maybe that's why it seemed to improve (shrink) code on Intel platforms... maybe having a few more registers, in addition to a compiler happening to recognize you were accessing that struct a lot, caused its base address to stay in a register. I'm sure it helped on some Motorola platforms like the 68000 series, because there were even more registers dedicated to being address pointers. Maybe on a small platform like the ATmega328 it doesn't matter, but it just seems to me one of the points of a struct is ensuring a series of related vars are compactly joined in memory. That being the case, I'd have thought repeated accesses to the same area of memory "ought" to make it easier for the compiler to recognize some possible shortcuts.

I guess I could try it and just see. It will just mean some careful global search /replace ops.

I'd expect minimal gains - unless your code is already very tight, there are likely easier places to look to save progmem.

westfw:
Accessing a structure via pointers can be somewhat more compact, because an “ld r1, y+n” is a two byte instruction, while “lds r1, adr” is a 4 byte instruction. But “n” is limited to rather small numbers, and there are only two index registers that can be used, so you are not likely to see an improvement with a large structure over a large program.

Well anyway, right... no significant change to either data or code space. Probably should have just done this test before I asked. My bad.