Value of uninitialized variable

  • Thread starter Philipp Klaus Krause
  • Start date
K

Keith Thompson

Tim Rentsch said:
I don't know where you're getting this. My reading is that, if the
width of _Bool is N > 1, then programs are allowed to use _Bool
bitfields of width up to N, and therefore implementations are
required to support them. (The quantity N may be any value between
1 and CHAR_BIT.) So if an implementation doesn't accept _Bool
bitfields of width > 1, I don't see how it's possible for the width
of _Bool in that implementation to be anything other than 1.

Why can't the width of _Bool exceed CHAR_BIT?
 
T

Tim Rentsch

Keith Thompson said:
Why can't the width of _Bool exceed CHAR_BIT?

Because of the value range rule [6.2.5p8] for integer types (_Bool
is an unsigned integer type), noting that _Bool has a conversion
rank less than all other standard integer types [6.3.1.1p1].
 
B

Ben Bacarisse

Tim Rentsch said:
Ben Bacarisse said:
Keith Thompson said:
[...]
gcc, for one, seems to give _Bool CHAR_BIT value bits. The effect is
that, given an object b of type_Bool, the expressions b and (_Bool)b
need not have the same value. Is _Bool the only type with this
property?

As of gcc 4.3.3, sizeof (_Bool) is 1, but it appears that only one of
the 8 bits is a value bit.

If I try to declare a bool bit field wider than one bit, I get:

error: width of 'b2' exceeds its type

As for b vs. (_Bool)b, an experiment indicates that they yield the
same result:

#include <stdio.h>

int main(void)
{
printf("sizeof (_Bool) = %zu\n", sizeof (_Bool));
_Bool b_two;
*(char*)&b_two = 2;
char c_two = 2;
printf("b_two = %d, (_Bool)b_two = %d\n", b_two, (_Bool)b_two);
printf("c_two = %d, (_Bool)c_two = %d\n", c_two, (_Bool)c_two);
return 0;
}

Output:

sizeof (_Bool) = 1
b_two = 2, (_Bool)b_two = 2
c_two = 2, (_Bool)c_two = 1

Hypothesis: _Bool has 1 value bit and 7 padding bits, and any
representation where any of the padding bits are 1 is a trap
representation. This means that any attempt to access the value
of b_two invokes undefined behavior -- even a cast to _Bool; the
compiler assumes that the stored value must be either 0 or 1, so
it doesn't need to normalize any non-zero value to 1, as it does
for types other than _Bool.

Perfectly possible. I don't think it is easy to tell if this is the
case of not. An implementation need not support bit-fields wider than
1 for _Bool even if _Bool has more than 1 value bit,

I don't know where you're getting this. My reading is that, if the
width of _Bool is N > 1, then programs are allowed to use _Bool
bitfields of width up to N, and therefore implementations are
required to support them.

I can't find the support for this. Bit-fields can't be wider than the
type's width (6.7.2.1 p3) but I don't see a requirement to support
bit-field width up to the width of the base type. I may simply have
missed it, of course.
(The quantity N may be any value between
1 and CHAR_BIT.) So if an implementation doesn't accept _Bool
bitfields of width > 1, I don't see how it's possible for the width
of _Bool in that implementation to be anything other than 1.

When N > 1, not implementing _Bool
bit-fields wider than 1 simply means that the implementation declines
to accept the invitation in the standard to support bit-fields up to
the width of the type.

<snip>
 
T

Tim Rentsch

Ben Bacarisse said:
Tim Rentsch said:
Ben Bacarisse said:
[...]
gcc, for one, seems to give _Bool CHAR_BIT value bits. The effect is
that, given an object b of type_Bool, the expressions b and (_Bool)b
need not have the same value. Is _Bool the only type with this
property?

As of gcc 4.3.3, sizeof (_Bool) is 1, but it appears that only one of
the 8 bits is a value bit.

If I try to declare a bool bit field wider than one bit, I get:

error: width of 'b2' exceeds its type

As for b vs. (_Bool)b, an experiment indicates that they yield the
same result:

#include <stdio.h>

int main(void)
{
printf("sizeof (_Bool) = %zu\n", sizeof (_Bool));
_Bool b_two;
*(char*)&b_two = 2;
char c_two = 2;
printf("b_two = %d, (_Bool)b_two = %d\n", b_two, (_Bool)b_two);
printf("c_two = %d, (_Bool)c_two = %d\n", c_two, (_Bool)c_two);
return 0;
}

Output:

sizeof (_Bool) = 1
b_two = 2, (_Bool)b_two = 2
c_two = 2, (_Bool)c_two = 1

Hypothesis: _Bool has 1 value bit and 7 padding bits, and any
representation where any of the padding bits are 1 is a trap
representation. This means that any attempt to access the value
of b_two invokes undefined behavior -- even a cast to _Bool; the
compiler assumes that the stored value must be either 0 or 1, so
it doesn't need to normalize any non-zero value to 1, as it does
for types other than _Bool.

Perfectly possible. I don't think it is easy to tell if this is the
case of not. An implementation need not support bit-fields wider than
1 for _Bool even if _Bool has more than 1 value bit,

I don't know where you're getting this. My reading is that, if the
width of _Bool is N > 1, then programs are allowed to use _Bool
bitfields of width up to N, and therefore implementations are
required to support them.

I can't find the support for this. Bit-fields can't be wider than the
type's width (6.7.2.1 p3) but I don't see a requirement to support
bit-field width up to the width of the base type. I may simply have
missed it, of course.

Programs (ie, programmers) have the right to use bitfields: "In
addition, a member may be declared to consist of a specified number of
bits (including a sign bit, if any)." [6.7.2.1p8.] The only
constraint on the specified number is that it be (an non-negative
integer constant expression with a value) no larger than the width of
the associated type. If I'm doing something the Standard explicitly
allows me to do, and I'm not violating any constraints, I think an
implementation is required to support it.
When N > 1, not implementing _Bool
bit-fields wider than 1 simply means that the implementation declines
to accept the invitation in the standard to support bit-fields up to
the width of the type.

I believe the explicit permission given in 6.7.2.1p8, plus the absence
of any other clauses that forbid it, makes accepting bitfields up to
the width of the associated type (including _Bool) not just an
invitation but a requirement.
 
K

Keith Thompson

Ben Bacarisse said:
I can't find the support for this. Bit-fields can't be wider than the
type's width (6.7.2.1 p3) but I don't see a requirement to support
bit-field width up to the width of the base type. I may simply have
missed it, of course.

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

N1256 changed the wording but not, I think, the meaning:

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.

If _Bool has a width of 8, a _Bool bit-field with a width of 8 is
not a constraint violation. What would be the implementation's
justification for rejecting it?
When N > 1, not implementing _Bool
bit-fields wider than 1 simply means that the implementation declines
to accept the invitation in the standard to support bit-fields up to
the width of the type.

May the implementation decline to accept the invitation in the
standard to support integer addition?
 
B

Ben Bacarisse

Tim Rentsch said:
Ben Bacarisse said:
Tim Rentsch said:
[...]
gcc, for one, seems to give _Bool CHAR_BIT value bits. The effect is
that, given an object b of type_Bool, the expressions b and (_Bool)b
need not have the same value. Is _Bool the only type with this
property?

As of gcc 4.3.3, sizeof (_Bool) is 1, but it appears that only one of
the 8 bits is a value bit.

If I try to declare a bool bit field wider than one bit, I get:

error: width of 'b2' exceeds its type

As for b vs. (_Bool)b, an experiment indicates that they yield the
same result:

#include <stdio.h>

int main(void)
{
printf("sizeof (_Bool) = %zu\n", sizeof (_Bool));
_Bool b_two;
*(char*)&b_two = 2;
char c_two = 2;
printf("b_two = %d, (_Bool)b_two = %d\n", b_two, (_Bool)b_two);
printf("c_two = %d, (_Bool)c_two = %d\n", c_two, (_Bool)c_two);
return 0;
}

Output:

sizeof (_Bool) = 1
b_two = 2, (_Bool)b_two = 2
c_two = 2, (_Bool)c_two = 1

Hypothesis: _Bool has 1 value bit and 7 padding bits, and any
representation where any of the padding bits are 1 is a trap
representation. This means that any attempt to access the value
of b_two invokes undefined behavior -- even a cast to _Bool; the
compiler assumes that the stored value must be either 0 or 1, so
it doesn't need to normalize any non-zero value to 1, as it does
for types other than _Bool.

Perfectly possible. I don't think it is easy to tell if this is the
case of not. An implementation need not support bit-fields wider than
1 for _Bool even if _Bool has more than 1 value bit,

I don't know where you're getting this. My reading is that, if the
width of _Bool is N > 1, then programs are allowed to use _Bool
bitfields of width up to N, and therefore implementations are
required to support them.

I can't find the support for this. Bit-fields can't be wider than the
type's width (6.7.2.1 p3) but I don't see a requirement to support
bit-field width up to the width of the base type. I may simply have
missed it, of course.

Programs (ie, programmers) have the right to use bitfields: "In
addition, a member may be declared to consist of a specified number of
bits (including a sign bit, if any)." [6.7.2.1p8.] The only
constraint on the specified number is that it be (an non-negative
integer constant expression with a value) no larger than the width of
the associated type. If I'm doing something the Standard explicitly
allows me to do, and I'm not violating any constraints, I think an
implementation is required to support it.

That's entirely reasonable. I am not sure why I read it so very
narrowly.

<snip>
 
B

Ben Bacarisse

Keith Thompson said:
C99 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.

N1256 changed the wording but not, I think, the meaning:

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.

If _Bool has a width of 8, a _Bool bit-field with a width of 8 is
not a constraint violation. What would be the implementation's
justification for rejecting it?

There is none that survives the cold light of day. Except, maybe, a
diffuse worry that an upper bound on what a program may use does not
seem like the clearest way to specify a lower bound on what the
implementation must support. But, as I said in reply to Tim, it seems
unreasonable, now, to read it as I did.

BTW, I think the meaning did change between C99 and n1256 because the
number of bits in an object is not the same is its width. Using the
n1256 wording

struct { unsigned field : sizeof(unsigned) * CHAR_BIT; } test;

must produce a diagnostic if unsigned int has padding bits but it must
not produce one under the C99 wording.
May the implementation decline to accept the invitation in the
standard to support integer addition?

That is (I hope!) a rhetorical question. I'll take it simply as an
indication of how silly you think my misunderstanding was!
 

Ask a Question

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.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top