Live data from Hacker News

What is a safest way to set all bits of a variable to true in C?

stackoverflow.com

11–20 of 30 posts

Re: What is a safest way to set all bits of a variable to true in C?

#11
post #5
post #4

Earlier quoted context omitted.

Because of two's complement and the way implicit conversions work.

It is independent of the representation of negative numbers on the machine, because of the conversion rules.

Because of two's complement, "-1" as a signed int/long is internally represented with all bits set to 1.

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.

Re: What is a safest way to set all bits of a variable to true in C?

#13
post #2

The next question: Why? (To clarify: I mean, "why do you care what the bits are set to".)

When converting a signed value to an unsigned value (and if the value cannot be represented with the unsigned type), the standard says: Add UINT_MAX + 1 until you get a valid unsigned value. Adding UINT_MAX + 1 to -1 gives you UINT_MAX.

Re: What is a safest way to set all bits of a variable to true in C?

#14
post #6

How many 'ones complement' machines exist?

The most well-known are 30-40 years old by now and predate ANSI C (=c89), some predate even K&R C. They also have 18- or 36-bit words and other oddities.

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.

Re: What is a safest way to set all bits of a variable to true in C?

#15
post #12

The "limits.h" (ISO C99 Standard) defines UINT_MAX as the maximum value for a variable of type unsigned int which is 4294967295 (0xffffffff).

Sigh:

"The contents of the header 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.

Re: What is a safest way to set all bits of a variable to true in C?

#16
post #5

Earlier quoted context omitted.

It is independent of the representation of negative numbers on the machine, because of the conversion rules.

Because of two's complement, "-1" as a signed int/long is internally represented with all bits set to 1. 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.

What I mean is that the conversion:

  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.

Re: What is a safest way to set all bits of a variable to true in C?

#17
post #2

The next question: Why? (To clarify: I mean, "why do you care what the bits are set to".)

I'm not sure what you mean.

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.)

Re: What is a safest way to set all bits of a variable to true in C?

#18
post #15
post #12

The "limits.h" (ISO C99 Standard) defines UINT_MAX as the maximum value for a variable of type unsigned int which is 4294967295 (0xffffffff).

Sigh : "The contents of the header 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.

Platforms differ, and the limits.h reflects this, that's the point. We should use the abstractions (the #defines) of the standard library, i.e. refer to these values by their names, that's the way to write portable software.

Re: What is a safest way to set all bits of a variable to true in C?

#19
post #17
post #2

The next question: Why? (To clarify: I mean, "why do you care what the bits are set to".)

I'm not sure what you mean. 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.)

So why not have a type that's "bitfield64" or something, and not worry how the machine represents your integer.

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.

Re: What is a safest way to set all bits of a variable to true in C?

#20
post #17

Earlier quoted context omitted.

I'm not sure what you mean. 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.)

So why not have a type that's "bitfield64" or something, and not worry how the machine represents your integer. 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.

That's a great idea, actually. In the projects I worked on, there were usually typedefs of various sizes, for example byte -> unsigned char, word -> unsigned int, dword -> unsigned long, etc.

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.

Post reply on HN