Question

I recently wrote some code that uses the same unsigned short to store two values, a result and an id, for example:

unsigned short data = new_id();
// result is either 0 or 1 so store it in the rightmost bit and move the id left
data = (data << 1) + get_result();
// ... later ...
// now we can print results like
printf("%u: %u\n", data & 1, data >> 1);

Would it be better to just use a struct to hold both values or is this type of thing common/acceptable? The program already stores so much memory I thought I'd start to find ways to decrease the memory it uses up.

Was it helpful?

Solution

Bitfields (but only if you really need to be tight on space - ie embedded systems)?

typedef struct id_result {
    unsigned int id : 15;
    unsigned int result : 1;
} id_result;

otherwise, yes, use a struct with more complete and meaningful definitions:

typedef uint16 IDTYPE; /* assuming uint16 exists elsewhere */

typedef struct id_result {
    IDTYPE id;
    bool result;
} id_result;

OTHER TIPS

Unless memory is incredibly tight, I would go the struct route. It's a lot clearer that way and easier for the next person who has to maintain your code.

I'm reminded of the time when the M68000 had 32 bit address registers but only 24 bits of them were actually used. Programmers did all sorts of "optimizations" to store information in those other 8 bits. Boy were their faces red when later versions of the chip, like the M68030, used all 32 bits.

Unless there is absolutely crunch of memory, I would rather go for simpler approach of having structure with two different variables. It increases the readability and reduces the maintenance efforts.

If this is done solely for the purpose of reducing the memory usage, then I believe you should not do it. You are better off using a structure with 2 shorts which makes the code much more readable. The amount of memory you save by doing this very tiny compared to the benefits you get by making the code more maintainable.

I suggest you first profile the system to find out whether there are any memory leaks or whether somebody is unnecessarily allocating large chunks of memory, etc., and then try to solve that problem. If still you can't find a solution, then find out which part of your program takes up most of the memory and try to redesign its memory allocation model.

To those who advise against conserving memory with bitfields: as the years go by and computers get more gigabytes, L1$ (the fast memory) remains just a few dozen kilobytes. For most applications today, a majority of time is spent waiting for slow memory to arrive in the L1$.

Since slow memory is the bottleneck in most applications, conserving memory with bitfields can actually significantly increase an application's speed. This wasn't as true twenty years ago.

Fitting both shorts into a single short yourself is, in my opinion, more work and more error-prone than using a struct. If using less memory is really required, you can specify bitfields with a struct :

struct myStruct {
int data:8;
int result:8;
};

It achieves the same memory-reducing result, while increasing the overall maintainability of the code.

Structs with bitfields are the most understandable implementation. If you don't use that approach, you could use a set of well-documented macros that pack and unpack the value pair into and out of 16-bit values.

Using structs/objects isn't necessarily the best or clearest approach.

Suppose you have a set of simple integer data points but they can be deleted or marked invalid, if you simply use the MSB to flag as 'don't use' then all you need to add to the algorithm is a

if ( item > 0 )
   item += blah

But if you have a struct then every bit of arithmatic now needs a member access

if ( item.valid() ) 
   item.setValue(item.getValue() + blah);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top