use of -1 to initial unsigned ints of various size to max value?

I'm initializing unsigned ints to their maximum value to indicate their initial and unstop state.

I can see that someone (possibly even me) would want to use larger sizes for some of these (at the expense of EEPROM or RAM) in future applications, particularly if they need more or longer of whatever its for.

Is initializing as (and for that matter testing for) -1 on these safe?

I'd been blithely doing this, and it occurs to me that int is the default for doing math--and I have or could have bytes and longs running around.

Is there a better way of achieving what I'm trying to do?

Setting unsigned types to -1 will wrap around to the maximum value of that type, for example if you set a byte to -1, its value will be 255, but the compiler may show a warning about it so I don't recommend doing that. What are you trying to do? Generally, 0 is a good initial value.

0 would have actual meaning for some things (like the start of EEPROM as it steps through), or run the sprinkler for 0 (skip it, but leave it in the program to be adjusted later), or time period (from 0 to 240 with two midnights), and such, although it makes sense for uninitialized time (which will go to unix seconds from either the master computer or the RTC).

If I understand correctly, a -1 in code will be a 16 bit value on arduino unless forced otherwise--isn't that the c++ rule?

My concern is that something like

unsigned long someVar=-1;

or

if (someVar==-1){

would use a -1 int of 0xFFFF, which might be 0x0000FFFF, or some other thing I haven't considered, if someone changes the size.

There are already constant integers defined just for that purpose. Look in 'stdint.h'. For example:

uint8_t dog = UINT8_MAX;

yes, but with the catch that the person making the change actually makes both changes . . . :o . . . I've been bit by such things . . . (my favorite being a long ago program for a startup in which a dingbat just didn't understand the difference between "create" and "edit" and kept whacking the data file. I changed the legacy code to handle stupidity, and probably saved a few precious bytes in the process, but . . . ")

A -1 is also nice and obvious--but unless coerced, isn't it a 16 bit -1 that won't match a 32 bit 0xFFFFFF?

dochawk:
If I understand correctly, a -1 in code will be a 16 bit value on arduino unless forced otherwise--isn't that the c++ rule?

Depends on the Arduino MCU. Literal -1 is int type and it depends on the MCU architecture if int is 16 or 32 bit type. Also for comparison the types are "promoted" so if you compare uint16_t and int then the uint16_t is actually promoted to int before comparison, so it's bad idea to compare directly to -1, because if int is 32bit then your uint16_t(-1) is actually 0xffff and not 0xffffffff, thus the comparison fails. You should always cast that -1 to the type you are comparing against, e.g. if(someVar==uint16_t(-1)), but of course you may change someVar type and this will fail again. So to play safe you should define the type for someVar with typedef and use that typedef in your -1 type cast. e.g. if(someVar==some_t(-1))

A -1 is also nice and obvious

Obviously what though ?

usong

(Wahtever type) x = -1;

is very common idiom and is the most portable way, guaranteeing the desired result in conforming implementations.

Google is your friend.

a7

(Wahtever type) x = -1;

The result of doing such an assignment will, of course, be very different depending on whether the data type is signed or unsigned

The expression sets all the bits to 1.

If in your world this is very different, you are right.

Try it. The OP wanted the maximum value of an unsigned int, this is what he gets.

If signed, all the bits are still set to one and you get a large negative number.

a7

alto777:
If signed, all the bits are still set to one and you get a large negative number.

Large in what sense? In two's complement format, all ones is -1.

Large in the sense that I should have counted to 32768 before adding such a totally wrong thing. -1, right. All bits set.

a7

OP: If you think it's really likely that the variable's size is going to be changed often. And you really think someone might forget to switch the initializer constant (UINT8_MAX, UINT16_MAX, etc), then maybe:

uint16_t integerVariableWhoSizeMightChange = 0;

void setup() {
  integerVariableWhoSizeMightChange--;
}

void loop() {}

Seems a little hacky, but it will always work.

In the real world, thiose constants must be # included, you don get them ardu-magically.

Initializing to -1 always works and is portable, so I suggest

int k = -1; /* set all bits */

I do like the decrement off zero, though!

Trick question: how do increment and decrement work on bool variables? Nothing to do with nothing, just got bit (no pun intended) by this one and a few mixed signed and unsigned computations. Tricky stuff, no substitute for trying things out.

a7

The expression sets all the bits to 1.

If in your world this is very different, you are right.

Whilst this is true, the value that the variable is set to will be very different for an unsigned variable to that of a signed variable