Problem with sizeof()

I've written a little timers utility as a function and declare it thus in the main programme :

extern byte timer(byte action, byte timer_no, unsigned long val);

enum timers { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer,
              mugging_timer
            };

const int maxtimers = sizeof(timers);

I got funny results, so then added

  Serial.print(maxtimers);

at the end of setup.

When ran in a nano it gave the value 2. Obviously it should be 7.

Any ideas?

Allan

It's an ugly idea, but if you're desperate, const int maxtimers = mugging_timer+1; I hope someone has a better idea...

Well, OK.

I can count, and could write maxtimers = 7 .

But I was hoping for something a bit more elegant.

Why should sizeof() get it wrong?

Allan

edit: It's actually ported from some stuff I wrote ages ago for a MSP430 target in the IAR IDE. Seemed OK there. /edit.

timers is a type now. It is the same size as an int.

Ah… so shouldn’t it then return 1? 7 is << 32567… Or does sizeof always presume bytes?

Any suggestions as to how should I do it?

thanks Allan

An enum is a compile-time abstraction that effectively does nothing but create a bunch of symbols. It does not HAVE a size, as it does not use any memory, and it's size certainly does not vary depending on how many members it has. Each symbol defined by the enum is an int, and sizeof(int) == 2. So, there is absolutely no "problem" with sizeof(), there is instead a problem with your expectation of what sizeof should do, which is quite different from what it is defined to do.

Regards,
Ray L.

allanhurst:
Obviously it should be 7.

No, obviously you WANT it to be 7.

allanhurst:
Ah… so shouldn’t it then return 1? 7 is << 32567… Or does sizeof always presume bytes?

The sizeof keyword always returns the number of bytes of a variable or data type.

I think your only option is to use something similar to what @aarg suggested:

const int maxtimers = mugging_timer+1

or

const int maxtimers = mugging_timer - start_timer + 1;

or

enum timers { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer, mugging_timer, LAST};

const int maxtimers = LAST;

Do you want to iterate with them?

extern byte timer(byte action, byte timer_no, unsigned long val);

enum timers { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer,
              mugging_timer
            };

const int timerList [] = { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer,
              mugging_timer
            };

const int maxtimers = sizeof(timerList[]);

I think...

Perhaps

const int maxtimers = sizeof(timerList) / sizeof(timerList[0]);

I think this is the best way to handle it:

enum timers { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer,
              mugging_timer, maxtimers
            };

it's less fragile than mugging_timer+1 because you just need to leave maxtimers as the last item if you add more.

Another trick I like to use with enum:

enum __attribute__((packed)) timers { start_timer, menu_timer, mod_temps_timer, mod_times_timer, heating_timer, at_temp_timer,
                                      mugging_timer, maxtimers
                                    };

Makes them 1 byte instead of 2. I used to avoid using enum before discovering that.