What is a safest way to set all bits of a variable to true in C?
stackoverflow.com
stackoverflow.com
This is a classic case of a readability issue. 0xFFFF is, in my mind, much clearer on your intention than -1. The only problem is that you're assuming a specific int size, but really, if you're working with bits, chances are good that you're working on a platform where you know the architecture size (at least on embedded platforms).
"The contents of the header <limits.h> are given below, in alphabetical order. The minimum magnitudes shown shall be replaced by implementation-defined magnitudes with the same sign."
#define UINT_MAX 65535
Key here is implementation-defined, with a minimum of 65535.I always liked the definition of true in Forth (all bits set to 1). It really made it a lot easier.
Compare that to non-ASCII systems (e.g. AS/400), which are still much in use now and probably have a sizable bit of C/C++ programs running on them (besides COBOL and Java).
If you're programming for one of the more common platforms (i.e., x86, x64, ARM, PowerPC, 68k, MIPS, SPARC, VAX, 8080/Z80, 6502), you'll be safe to assume that ((unsigned)-1), ((unsigned)~0) and ~((unsigned)0) are all the same.
That makes me very surprised by (1) the number of up-votes, and (2) the green "check" mark of approval.
unsigned int foo = -1;
will set foo to 0xFFFF..., automatically setting all bits to 1 regardless of the number of bits in int types and without respect to the representation of negative numbers.Weird bit of arcana. Below is my mistaken comment. (Notice that I pretended that UINT_MAX is not all 1s, which is silly. I suppose I made that mistake because I "couldn't be wrong" or something.)
As far as I know, your definition can't be inferred from the C standard. The answer itself acknowledges that -1 doesn't yield 0xFFFF… on every platform. The only guarantee is that it will yield UINT_MAX, which is not what was asked.
Otherwise, that would mean that C basically mandates a two's complement representation. Does it?
(To clarify: I mean, "why do you care what the bits are set to".)
Conversion rules are pretty basic, i.e. there is no conversion done on the actual value, so that's why it works: converting "-1" to an unsigned int yields MAX_UINT.
unsigned int flags = -1;
always works, regardless of whether negative numbers are represented in two's complement, one's complement, or sign/magnitude on the underlying hardware.If you meant "why worry about bits, you should be dealing with values", then there are plenty of cases where that isn't true. Lots of programs (e.g. embedded programs) have to deal with actual bits, not with the values themselves. Just as an example, flags.
(I don't know if this is what you meant, so apologies if I misunderstood your question.)
This seems like too much abstraction for a C programmer, I know, but there is already precedent. int and int * are not the same type; if you use one as the other the compiler will tell you not to, even though they are the exact same bits in memory.
We made sure that each one of these had the correct bit amounts in the mapping, and that way, you always knew exactly how many bits you were working with, which is important in embedded systems (where memory is important, and where you usually have structures which directly map to e.g. ip headers, so you need exact sizes).
By the way, even the words byte/word/dword might cause confusion, cause none of them are well defined either. Some architectures assign a word 16 bits, some 32 bits. And believe it or not, some architectures even assign bytes a number of bits different than 8! The "officially correct" term, I believe, is Octet, which is defined as 8 bits. Of course, we just decided internally what we meant by byte, word and dword, and that worked fine.