G
Guest
Do you have a machine and C compiler that supports _Bool? Is it
mythical?
The type _Bool needn't necessarily have padding bits. In fact, in
every implementation I inspected it hasn't.
Do you have a machine and C compiler that supports _Bool? Is it
mythical?
[email protected] said:The type _Bool needn't necessarily have padding bits. In fact, in
every implementation I inspected it hasn't.
Ben Bacarisse said:If you set bits directly in the representation of a _Bool, how can you
tell if those bits are value or padding bits? They might look like
value bits (in that you get a value > 1 from the _Bool object) but that
could just be the result of undefined behaviour from a representation
that does not "represent a value of the object type" (6.2.6.1 p5).
[...]
Unfortunately, the paragraph in question was modified by TC2 and I don't
have the base C99 document to know what it said before. It's possible
that C99 (without TC2) does not even provide this method of detecting
the width of a _Bool.
Keith Thompson said:Ben Bacarisse said:If you set bits directly in the representation of a _Bool, how can you
tell if those bits are value or padding bits? They might look like
value bits (in that you get a value > 1 from the _Bool object) but that
could just be the result of undefined behaviour from a representation
that does not "represent a value of the object type" (6.2.6.1 p5).
[...]
Unfortunately, the paragraph in question was modified by TC2 and I don't
have the base C99 document to know what it said before. It's possible
that C99 (without TC2) does not even provide this method of detecting
the width of a _Bool.
TC2 didn't touch 6.2.6.1p5, which says:
Ben Bacarisse said:Keith Thompson said:Ben Bacarisse said:If you set bits directly in the representation of a _Bool, how can you
tell if those bits are value or padding bits? They might look like
value bits (in that you get a value > 1 from the _Bool object) but that
could just be the result of undefined behaviour from a representation
that does not "represent a value of the object type" (6.2.6.1 p5).
[...]
Unfortunately, the paragraph in question was modified by TC2 and I don't
have the base C99 document to know what it said before. It's possible
that C99 (without TC2) does not even provide this method of detecting
the width of a _Bool.
TC2 didn't touch 6.2.6.1p5, which says:
No indeed. I was not clear. After talking about 6.2.6.1 p5 I moved on
to the only way I could think of for actually testing the number of
value bits in the type _Bool. The ambiguous "paragraph in question" is
the one that imposes a constraint on the size of a bit-field: 6.7.2.1
p3. This is the one whose pre-TC2 contents are a mystery to me.
Sorry to have misled you into a wild corrigenda chase.
<snip>
Keith Thompson said:Ben Bacarisse said:Keith Thompson said:[...]
If you set bits directly in the representation of a _Bool, how can you
tell if those bits are value or padding bits? They might look like
value bits (in that you get a value > 1 from the _Bool object) but that
could just be the result of undefined behaviour from a representation
that does not "represent a value of the object type" (6.2.6.1 p5).
[...]
Unfortunately, the paragraph in question was modified by TC2 and I don't
have the base C99 document to know what it said before. It's possible
that C99 (without TC2) does not even provide this method of detecting
the width of a _Bool.
TC2 didn't touch 6.2.6.1p5, which says:
No indeed. I was not clear. After talking about 6.2.6.1 p5 I moved on
to the only way I could think of for actually testing the number of
value bits in the type _Bool. The ambiguous "paragraph in question" is
the one that imposes a constraint on the size of a bit-field: 6.7.2.1
p3. This is the one whose pre-TC2 contents are a mystery to me.
Sorry to have misled you into a wild corrigenda chase.
<snip>
In C99, 6.7.2.1p3 says:
The expression that specifies the width of a bit-field shall be
an integer constant expression that has nonnegative value that
shall not exceed the number of bits in an object of the type
that is specified if the colon and expression are omitted. If
the value is zero, the declaration shall have no declarator.
In N1256, it says:
The expression that specifies the width of a bit-field shall
be an integer constant expression with a nonnegative value
that does not exceed the width of an object of the type that
would be specified were the colon and expression omitted. If
the value is zero, the declaration shall have no declarator.
The change is in response to Defect Report #262,
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_262.htm>.
Apart from some cleanup of the wording, the effect is to refer to
the "width" of the type rather than the ambiguous "number of bits".
It's not clear (to me, anyway) what the width of _Bool is supposed to
be. It seems to me that the Standard doesn't preclude either of the
following (assume CHAR_BIT==8 and sizeof(_Bool)==1):
_Bool has 1 value bit and 7 padding bits and can only represent
the values 0 and 1; its width is 1.
_Bool has 8 value bits and can represent values from 0 to
255 inclusive (but storing a value other than 0 or 1 requires
tricks); its width is 8.
More concretely, what is the required behavior of this program?
#include <stdio.h>
int main(void)
{
if (sizeof(_Bool) == 1) {
_Bool b;
*(unsigned char*)&b = 2;
printf("b = %d\n", b);
}
else {
puts("sizeof(_Bool) != 1");
}
return 0;
}
Assuming sizeof(_Bool)==1, must it print "b = 2", or is the behavior
undefined?
Keith Thompson said:More concretely, what is the required behavior of this program?
#include <stdio.h>
int main(void)
{
if (sizeof(_Bool) == 1) {
_Bool b;
*(unsigned char*)&b = 2;
printf("b = %d\n", b);
}
else {
puts("sizeof(_Bool) != 1");
}
return 0;
}
Assuming sizeof(_Bool)==1, must it print "b = 2", or is the behavior
undefined?
Keith Thompson said:_Bool is also the only predefined integer type that doesn't have _MIN
and _MAX macros in <limits.h> or <stdint.h>.
Keith Thompson said:Ben Bacarisse said:Keith Thompson <[email protected]> writes: [...]It's not clear (to me, anyway) what the width of _Bool is supposed to
be. It seems to me that the Standard doesn't preclude either of the
following (assume CHAR_BIT==8 and sizeof(_Bool)==1):
_Bool has 1 value bit and 7 padding bits and can only represent
the values 0 and 1; its width is 1.
_Bool has 8 value bits and can represent values from 0 to
255 inclusive (but storing a value other than 0 or 1 requires
tricks); its width is 8.
I think both are permitted along with all points in between (i.e. any
width from 1 to CHAR_BIT seems to me to be permitted). I can't find any
text that imposes any tighter constraints on the implementation.
Are widths exceeding CHAR_BIT forbidden? I know that _Bool is required
to have a lower rank than any other standard integer type, but I don't
think that implies it can't have a wider range than unsigned char
(though it could cause some interesting effects if it does).
Since they are, by definition, 0 and 1, there didn't seem to be much
point.
Seebs said:Are they, though?
If you can write a value other than zero or
one in which isn't a trap representation (using the unsigned-
char interface), maybe the largest value the type can hold
should be BOOL_MAX, even though it might not be 1.
What other values can you assign to it?
Hmm... Playing advocate... if you had said...
If you can write a value other than 0..UINT_MAX which isn't a
trapresentation (using the unsigned-char interface), maybe the
largest value the type can hold should be REAL_UINT_MAX, even
though it might not be UINT_MAX.
How much sense would that make?
Seebs said:You can't assign other values to it, but it's not obvious
that a value outside that range can't be stored in it. We
know for sure that it can't possibly be a one-bit physical
type -- it has to have at least CHAR_BIT bits of physical
storage.
Shao said:I was under the impression that if we do not take the address of
non-bit-field objects with type '_Bool', that the implementation could
pack them together and reads/stores of their values could be translated
as bitwise operations, perhaps on any old register.
Since only 0 or 1 can be assigned and it's a "standard unsigned integer
type", things are pretty simple. If we take an address, maybe not.
Why don't you write a little program and let the computer figure it
out?
Seebs said:Peter Nilsson said:What other values can you assign to [_Bool]?
You can't assign other values to it, but it's not obvious
that a value outside that range can't be stored in it.
We know for sure that it can't possibly be a one-bit
physical type -- it has to have at least CHAR_BIT bits
of physical storage.
None, because UINT_MAX is defined in terms of the values
that are represented in the type
-- but _Bool, never really says that you can't represent
other values, just that anything assigned into it turns
into a zero or one.
Seebs said:You can't assign other values to it, but it's not obviousPeter Nilsson said:What other values can you assign to [_Bool]?
that a value outside that range can't be stored in it.
It's not obvious that a value outside the range of unsigned
int can't be stored in an unsigned int with padding bits.
The fact that _Bool's width is narrower than a character is
no different to any other padded unsigned type being narrower
than it's byte size * CHAR_BIT bits.
How do you know? I ask because it is easy to confuse value bits with
the undefined behaviour of padding bits (I've made that mistake myself
in this very newsgroup).
[email protected] said:I know by code inspection. The assignment of a _Bool object to an int
object was compiled to a plain move of a 32 bit word to a 32 bit word.
If the _Bool object would have padding bits, this move weren't
sufficient for the conversion to int.
(By the way, I don't see how one can confuse bits with behaviour.)
What part of the semantics of _Bool and/or int does this plain move
violate?
If, for example, all non-zero settings of 31 padding bits correspond to
trap representations then the conversion to int is undefined if anything
other than the single value bit is set (6.2.6.1 p5). Hence a plain copy
is as good an anything else.
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.