Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bitwise Operator Effects on Padding Bits

177 views
Skip to first unread message

Shao Miller

unread,
Sep 6, 2010, 5:24:52 PM9/6/10
to
Hello folks. I hope you're having a nice day today.

Which of the following groups of bits in an integer type will be
complemented by the unary '~' bitwise operator?:

- value bits
- padding bits
- the sign bit (for signed integer types)

H Vlems

unread,
Sep 6, 2010, 5:39:30 PM9/6/10
to

Why don't you write a little program and let the computer figure it
out?

Shao Miller

unread,
Sep 6, 2010, 5:53:14 PM9/6/10
to

Ok, thanks. Perhaps I could use the object representation to examine
the bits, would that make sense? If so, how do I know which bits in the
object representation correspond to the aforementioned groups?

Ian Collins

unread,
Sep 6, 2010, 6:08:51 PM9/6/10
to

Find one of those mythical machines with padding bits and have look!

--
Ian Collins

Eric Sosman

unread,
Sep 6, 2010, 6:18:48 PM9/6/10
to
On 9/6/2010 5:24 PM, Shao Miller wrote:
> Hello folks. I hope you're having a nice day today.
>
> Which of the following groups of bits in an integer type will be
> complemented by the unary '~' bitwise operator?:
>
> - value bits

Affected.

> - padding bits

May be affected, may not be. Definitely not guaranteed
to be inverted.

> - the sign bit (for signed integer types)

Affected. The consequences are not assuredly useful.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Shao Miller

unread,
Sep 6, 2010, 6:27:50 PM9/6/10
to

Firstly, thank you for your valuable response, Mr. E. Sosman.

I did see an example in the C1X draft where a padding bit might be a
parity bit. My impression was that the bit _might_ be complemented
during the bitwise '~', but only as a matter of co-incidence, and not
because '~' is defined to complement padding bits. Would you agree to that?

Also, do you happen to know if any standard of C explicitly defines
this? And if so, which sections might be critical to keep in mind for
that determination? I looked, but couldn't find anything, so thought
I'd ask for expert thoughts in this forum.

Seebs

unread,
Sep 6, 2010, 6:29:58 PM9/6/10
to
On 2010-09-06, H Vlems <hvl...@freenet.de> wrote:
> On Sep 6, 11:24?pm, Shao Miller <sha0.mil...@gmail.com> wrote:
>> Hello folks. ?I hope you're having a nice day today.

>> Which of the following groups of bits in an integer type will be
>> complemented by the unary '~' bitwise operator?:

>> - value bits
>> - padding bits
>> - the sign bit (for signed integer types)

> Why don't you write a little program and let the computer figure it
> out?

What good would that do? Maybe some implementations differ in what they
do. The correct solution is to read the specification and find out what
it says. Or ask people who are likely to know.

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Shao Miller

unread,
Sep 6, 2010, 6:46:38 PM9/6/10
to
Seebs wrote:
> On 2010-09-06, H Vlems <hvl...@freenet.de> wrote:
>> On Sep 6, 11:24?pm, Shao Miller <sha0.mil...@gmail.com> wrote:
>>> Hello folks. ?I hope you're having a nice day today.
>>> Which of the following groups of bits in an integer type will be
>>> complemented by the unary '~' bitwise operator?:
>
>>> - value bits
>>> - padding bits
>>> - the sign bit (for signed integer types)
>
>> Why don't you write a little program and let the computer figure it
>> out?
>
> What good would that do? Maybe some implementations differ in what they
> do. The correct solution is to read the specification and find out what
> it says. Or ask people who are likely to know.

Thanks, Mr. P. Seebach. I fully agree with your correct solution.

Ben Bacarisse

unread,
Sep 6, 2010, 6:51:38 PM9/6/10
to
Ian Collins <ian-...@hotmail.com> writes:

Do you have a machine and C compiler that supports _Bool? Is it
mythical?

I think you are conflating padding bits with trap representations.
Padding bits are very common, but machines with trap representations
(which might well derive from the padding bits) are rarer.

--
Ben.

Ian Collins

unread,
Sep 6, 2010, 6:53:57 PM9/6/10
to
On 09/ 7/10 10:51 AM, Ben Bacarisse wrote:
> Ian Collins<ian-...@hotmail.com> writes:
>
>> On 09/ 7/10 09:53 AM, Shao Miller wrote:
>>> H Vlems wrote:
>>>> On Sep 6, 11:24 pm, Shao Miller<sha0.mil...@gmail.com> wrote:
>>>>> Hello folks. I hope you're having a nice day today.
>>>>>
>>>>> Which of the following groups of bits in an integer type will be
>>>>> complemented by the unary '~' bitwise operator?:
>>>>>
>>>>> - value bits
>>>>> - padding bits
>>>>> - the sign bit (for signed integer types)
>>>>
>>>> Why don't you write a little program and let the computer figure it
>>>> out?
>>>
>>> Ok, thanks. Perhaps I could use the object representation to examine the
>>> bits, would that make sense? If so, how do I know which bits in the
>>> object representation correspond to the aforementioned groups?
>>
>> Find one of those mythical machines with padding bits and have look!
>
> Do you have a machine and C compiler that supports _Bool? Is it
> mythical?

Several...

> I think you are conflating padding bits with trap representations.
> Padding bits are very common, but machines with trap representations
> (which might well derive from the padding bits) are rarer.

I think you are correct, sorry for the noise.

--
Ian Collins

Eric Sosman

unread,
Sep 6, 2010, 8:47:43 PM9/6/10
to
On 9/6/2010 6:27 PM, Shao Miller wrote:
> Eric Sosman wrote:
>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>> Hello folks. I hope you're having a nice day today.
>>>
>>> Which of the following groups of bits in an integer type will be
>>> complemented by the unary '~' bitwise operator?:
>>>
>>> - value bits
>>
>> Affected.
>>
>>> - padding bits
>>
>> May be affected, may not be. Definitely not guaranteed
>> to be inverted.
>>
>>> - the sign bit (for signed integer types)
>>
>> Affected. The consequences are not assuredly useful.
>
> Firstly, thank you for your valuable response, Mr. E. Sosman.

You are most welcome, Mr./Mrs./Miss/Ms./Mlle./Sra. Shao M.

> I did see an example in the C1X draft where a padding bit might be a
> parity bit. My impression was that the bit _might_ be complemented
> during the bitwise '~', but only as a matter of co-incidence, and not
> because '~' is defined to complement padding bits. Would you agree to that?

Yes, in much the same way I'd agree to "Crows are blue or non-blue."
The settings (if any) of padding bits (if any) are unspecified, always.

> Also, do you happen to know if any standard of C explicitly defines
> this?

Yes.

> And if so, which sections might be critical to keep in mind for
> that determination?

6.2.6.2p1, 6.2.6.2p5.

> I looked, but couldn't find anything, so thought I'd
> ask for expert thoughts in this forum.

I never set much stock in the "biorhythms" craze of a few decades
back, but the sight of Mr./Mrs./Miss/Ms./Mlle./Sra. Shao M. oscillating
between ignorance one day and arrogance the next makes me wonder
whether there *was* something to it, after all.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Shao Miller

unread,
Sep 6, 2010, 9:32:53 PM9/6/10
to
Eric Sosman wrote:
> On 9/6/2010 6:27 PM, Shao Miller wrote:
>> Eric Sosman wrote:
>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>>> Hello folks. I hope you're having a nice day today.
>>>>
>>>> Which of the following groups of bits in an integer type will be
>>>> complemented by the unary '~' bitwise operator?:
>>>>
>>>> - value bits
>>>
>>> Affected.
>>>
>>>> - padding bits
>>>
>>> May be affected, may not be. Definitely not guaranteed
>>> to be inverted.
>>>
>>>> - the sign bit (for signed integer types)
>>>
>>> Affected. The consequences are not assuredly useful.
>>
>> Firstly, thank you for your valuable response, Mr. E. Sosman.
>
> You are most welcome, Mr./Mrs./Miss/Ms./Mlle./Sra. Shao M.

Oh please feel free to call me by my first name. Hopefully it is
sufficiently unique that I'll know who you mean. ;)

>
>> I did see an example in the C1X draft where a padding bit might be a
>> parity bit. My impression was that the bit _might_ be complemented
>> during the bitwise '~', but only as a matter of co-incidence, and not
>> because '~' is defined to complement padding bits. Would you agree to
>> that?
>
> Yes, in much the same way I'd agree to "Crows are blue or non-blue."
> The settings (if any) of padding bits (if any) are unspecified, always.

Right. The padding bits will either be set or unset... I was more
asking about whether they are directly complemented by the unary '~'
operator.

>
>> Also, do you happen to know if any standard of C explicitly defines
>> this?
>
> Yes.
>
>> And if so, which sections might be critical to keep in mind for
>> that determination?
>
> 6.2.6.2p1, 6.2.6.2p5.

I've read 6.2.6.2 several times but didn't read anything about whether
or not unary '~' (and other bitwise friends) are restricted to
particular bit groups. I think it's clear from those two points you
reference that the padding bits are unspecified. What I'm wondering is
if they must toggle when one applies unary '~' to an operand. Still
unspecified, but in the other state. My interpretation is that they are
not defined to toggle, but I cannot prove it with the Standard.

If they _are_ defined to toggle, then that could very well be behaviour
that could come in handy... It limits what roles padding bits can serve
and we can derive expectations for the object representations of the
results of operations which can then be used to determine
characteristics of the environment. I'm not going to bet on it.

>
>> I looked, but couldn't find anything, so thought I'd
>> ask for expert thoughts in this forum.
>
> I never set much stock in the "biorhythms" craze of a few decades
> back, but the sight of Mr./Mrs./Miss/Ms./Mlle./Sra. Shao M. oscillating
> between ignorance one day and arrogance the next makes me wonder
> whether there *was* something to it, after all.
>

Why offer this? Feel free to contact me about any arrogance you have or
do perceive and I will try to address it. That's always been the case.
It is only since joining this forum that anyone has ever offered such
negative criticism about me and frankly, I'd really rather people
didn't. That means fixing the problem through understanding or
realizing that someone is just being nasty. Ultimately, I fail to
understand what such has to do with C and fail to understand why such is
worth sharing with everyone. Please keep in mind that your perceptions
are relative.

James Dow Allen

unread,
Sep 6, 2010, 11:15:11 PM9/6/10
to
On Sep 7, 4:39 am, H Vlems <hvl...@freenet.de> wrote:
> Why don't you write a little program and let the computer figure it
> out?

In the majority of cases, where real-program testing is
the obvious and correct way to get an answer, posters are
warned NOT to get their answers this way!

In the cases where posters want portable code, and testing
on a given machine is irrelevant, this answer is given!

Comp.lang.c. Great fun!!

James

Francois Grieu

unread,
Sep 7, 2010, 1:00:45 AM9/7/10
to
On 07/09/2010 03:32, Shao Miller wrote:
> Eric Sosman wrote:
>> On 9/6/2010 6:27 PM, Shao Miller wrote:
>>> Eric Sosman wrote:
>>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>>>> Hello folks. I hope you're having a nice day today.
>>>>>
>>>>> Which of the following groups of bits in an integer type will be
>>>>> complemented by the unary '~' bitwise operator?:
>>>>>
>>>>> - value bits
>>>>
>>>> Affected.
>>>>
>>>>> - padding bits
>>>>
>>>> May be affected, may not be. Definitely not guaranteed
>>>> to be inverted.

I'm unsure about that, see below.

Also see 6.5.3.3p1 and See 6.5.3.3p4

The operand of the unary ~ operator shall have integer type.

The result of the ~ operator is the bitwise complement of its
(promoted) operand (that is, each bit in the result is set if
and only if the corresponding bit in the converted operand is
not set). The integer promotions are performed on the operand,
and the result has the promoted type. If the promoted type is
an unsigned type, the expression ~E is equivalent to the
maximum value representable in that type minus E.

Because of *each*, I read this, even combined with 6.2.6.2,
as implying ~ inverts padding bits. One thing is sure: whatever
effect there is on padding bits has no incidence on the value
represented. The point is moot since the padding bit is a dodo,
or a even a dahu AFAIK.

Effect of ~ on the value and the possible occurrence of a trap
representation depends on if the promoted type is signed or
unsigned, and in the former case of which of the options in
6.2.6.2p2 (sign and magnitude, two's complement, one's
complement) is in effect.


Speaking of dodos, anyone know a machine, with a C compiler
in actual use, that does not use two's complement? Is there
support for keeping only that and/or dropping padding bits
in integer types in a forthcoming C standard?

Francois Grieu

Ben Bacarisse

unread,
Sep 7, 2010, 7:54:47 AM9/7/10
to
Francois Grieu <fgr...@gmail.com> writes:
<snip>

>>> On 9/6/2010 6:27 PM, Shao Miller wrote:
>>>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
<snipped in places to recover just the original context>

>>>>>> Hello folks. I hope you're having a nice day today.
>>>>>>
>>>>>> Which of the following groups of bits in an integer type will be
>>>>>> complemented by the unary '~' bitwise operator?:
>>>>>>
>>>>>> - value bits
>>>>>> - padding bits

>>>>>> - the sign bit (for signed integer types)
<snip>

> Also see 6.5.3.3p1 and See 6.5.3.3p4
>
> The operand of the unary ~ operator shall have integer type.
>
> The result of the ~ operator is the bitwise complement of its
> (promoted) operand (that is, each bit in the result is set if
> and only if the corresponding bit in the converted operand is
> not set). The integer promotions are performed on the operand,
> and the result has the promoted type. If the promoted type is
> an unsigned type, the expression ~E is equivalent to the
> maximum value representable in that type minus E.
>
> Because of *each*, I read this, even combined with 6.2.6.2,
> as implying ~ inverts padding bits. One thing is sure: whatever
> effect there is on padding bits has no incidence on the value
> represented.

That's a strong argument but it's not bullet proof. The operand is
promoted and integer promotion is all about values not representations.
Even if the type does not change, integer promotion is guaranteed to
preserve the value but not the representation.

> The point is moot since the padding bit is a dodo,
> or a even a dahu AFAIK.

As I keep saying, what about _Bool?

I think the question is moot for another reason altogether. Even if ~
is absolutely forced to invert a "value" that somehow keeps the padding
bits, none of assignment, parameter passing nor initialisation are
required to preserve them so how can you tell? I take Shao Miller's
intent to be to find some way to inspect them and that requires that the
result of ~E finds itself, unchanged, inside some object or other.

<snip>
--
Ben.

Eric Sosman

unread,
Sep 7, 2010, 8:06:26 AM9/7/10
to
On 9/7/2010 1:00 AM, Francois Grieu wrote:
> On 07/09/2010 03:32, Shao Miller wrote:
>> Eric Sosman wrote:
>>> On 9/6/2010 6:27 PM, Shao Miller wrote:
>>>> Eric Sosman wrote:
>>>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>>>>> Hello folks. I hope you're having a nice day today.
>>>>>>
>>>>>> Which of the following groups of bits in an integer type will be
>>>>>> complemented by the unary '~' bitwise operator?:
>>>>>> [...]

>>>>>
>>>>>> - padding bits
>>>>>
>>>>> May be affected, may not be. Definitely not guaranteed
>>>>> to be inverted.
>
> I'm unsure about that, see below.
> [...]

> Also see 6.5.3.3p1 and See 6.5.3.3p4
>
> The operand of the unary ~ operator shall have integer type.
>
> The result of the ~ operator is the bitwise complement of its
> (promoted) operand (that is, each bit in the result is set if
> and only if the corresponding bit in the converted operand is
> not set). The integer promotions are performed on the operand,
> and the result has the promoted type. If the promoted type is
> an unsigned type, the expression ~E is equivalent to the
> maximum value representable in that type minus E.
>
> Because of *each*, I read this, even combined with 6.2.6.2,
> as implying ~ inverts padding bits.

I believe 6.2.6.2's "The values of any padding bits are
unspecified" should be taken as the overriding statement of how
padding bits are treated. In its description of expressions,
6.5 does not seem to mention padding bits at all, so I don't
think you can take the absence of an "except for padding bits"
clause as indicating that the ~ operator specifies anything
about them. The descriptions of & and | and << and >> also
omit mention of padding bits, yet I'm confident there's no
claim about what >>, say, does with padding in its operand.

Back to ~, though: The reading you favor seems at odds with
footnote 44, which describes the possible use of a padding bit
as a parity bit. If the value bits and sign bit taken together
come to an even number of bits and you invert them all, the
parity of the whole remains unchanged. So if ~ also inverted
a parity bit, the result would have bad parity -- and this would
contradict the assertion that a valid arithmetic operation on a
valid value cannot produce a trap representation. Footnotes are
of course non-normative, but they offer a guide to how the writers
expected the Standard to be understood.

--
Eric Sosman
eso...@ieee-dot-org.invalid

Ben Bacarisse

unread,
Sep 7, 2010, 8:13:29 AM9/7/10
to
Shao Miller <sha0....@gmail.com> writes:

> Eric Sosman wrote:
>> On 9/6/2010 6:27 PM, Shao Miller wrote:
>>> Eric Sosman wrote:
>>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>>>> Hello folks. I hope you're having a nice day today.
>>>>>
>>>>> Which of the following groups of bits in an integer type will be
>>>>> complemented by the unary '~' bitwise operator?:
>>>>>
>>>>> - value bits
>>>>
>>>> Affected.
>>>>
>>>>> - padding bits
>>>>
>>>> May be affected, may not be. Definitely not guaranteed
>>>> to be inverted.
>>>>
>>>>> - the sign bit (for signed integer types)
>>>>
>>>> Affected. The consequences are not assuredly useful.

<snip>


>>> I did see an example in the C1X draft where a padding bit might be a
>>> parity bit. My impression was that the bit _might_ be complemented
>>> during the bitwise '~', but only as a matter of co-incidence, and not
>>> because '~' is defined to complement padding bits. Would you agree
>>> to that?
>>
>> Yes, in much the same way I'd agree to "Crows are blue or non-blue."
>> The settings (if any) of padding bits (if any) are unspecified, always.
>
> Right. The padding bits will either be set or unset... I was more
> asking about whether they are directly complemented by the unary '~'
> operator.

I don't think this is well-formed question. For one thing, ~ operates
on a promoted operand and I don't think promotion preserves padding
bits. In fact, I don't think promotion results in the kind of "thing"
that can even have padding -- it results in a value. Secondly, padding
bits reside in objects and the result of ~E is not an object. Even if
we speculate that promotion somehow results in a "value" with padding
bits and the ~ must invert them, how could you ever tell?

In effect I am asking what the question means in terms of C programs.
What programs are you imagining whose behaviour is altered by the answer
to your question?

<snip>


> If they _are_ defined to toggle, then that could very well be
> behaviour that could come in handy... It limits what roles padding
> bits can serve and we can derive expectations for the object
> representations of the results of operations which can then be used to
> determine characteristics of the environment. I'm not going to bet on
> it.

This bit seems very vague. What are these expectations and what might
they enable us to determine about the environment?

<snip>
--
Ben.

Shao Miller

unread,
Sep 7, 2010, 6:22:38 PM9/7/10
to
Francois Grieu wrote:
> On 07/09/2010 03:32, Shao Miller wrote:
>> Eric Sosman wrote:
>>> On 9/6/2010 6:27 PM, Shao Miller wrote:
>>>> Eric Sosman wrote:
>>>>> On 9/6/2010 5:24 PM, Shao Miller wrote:
>>>>>> Hello folks. I hope you're having a nice day today.
>>>>>>
>>>>>> Which of the following groups of bits in an integer type will be
>>>>>> complemented by the unary '~' bitwise operator?:
>>>>>>
>>>>>> - value bits
>>>>> Affected.
>>>>>
>>>>>> - padding bits
>>>>> May be affected, may not be. Definitely not guaranteed
>>>>> to be inverted.
>
> I'm unsure about that, see below.
>
>>>>>> - the sign bit (for signed integer types)
>>>>> Affected. The consequences are not assuredly useful.
> ... ... ...

> The operand of the unary ~ operator shall have integer type.
>
> ... ... ...

> Because of *each*, I read this, even combined with 6.2.6.2,
> as implying ~ inverts padding bits. One thing is sure: whatever
> effect there is on padding bits has no incidence on the value
> represented. The point is moot since the padding bit is a dodo,
> or a even a dahu AFAIK.
> ... ... ...

Thank you very much for your response, Mr. F. Grieu. There is
definitely some food for thought in your post. Perhaps it's moot, as
you say.

Keith Thompson

unread,
Sep 7, 2010, 6:33:54 PM9/7/10
to
Shao Miller <sha0....@gmail.com> writes:
> Francois Grieu wrote:
[snip]

>
> Thank you very much for your response, Mr. F. Grieu. There is
> definitely some food for thought in your post. Perhaps it's moot, as
> you say.

Just a thought: You could avoid any uncertainty about how to address
people by not addressing them by name at all. For example, it's
obvious from the attribution line who I'm addressing; there's no need
to mention your name.

I don't suggest that there's anything wrong with the way you're
doing it, but it is a trifle unusual and I personally find that it
distracts (*very* slightly) from the points you make.

Feel free to ignore this.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Shao Miller

unread,
Sep 7, 2010, 6:52:15 PM9/7/10
to

Thank you for your valuable response as usual, Ben.

If I understand your point, it's that the padding bits of the operand
mightn't be preserved during promotion, so that information is
theoretically gone before bit-toggling takes place. That's good reasoning.

We do also have 6.3p2 regarding preservation of representation. Perhaps
that could apply for those few cases where promotion causes no change in
type. But that's now fewer cases, anyway.

>
>> The point is moot since the padding bit is a dodo,
>> or a even a dahu AFAIK.
>
> As I keep saying, what about _Bool?
>

And bit-fields, for that matter. If we have an 'int' bit-field, since
there's no type change in promotion, I wonder if the other bits in the
surrounding storage unit are preserved in the representation of the
promoted result. What do you think?

> I think the question is moot for another reason altogether. Even if ~
> is absolutely forced to invert a "value" that somehow keeps the padding
> bits, none of assignment, parameter passing nor initialisation are
> required to preserve them so how can you tell? I take Shao Miller's
> intent to be to find some way to inspect them and that requires that the
> result of ~E finds itself, unchanged, inside some object or other.

Yup. You're right on, and this would toss away inspection value unless
6.3p2 preserves padding bits in an assignment.

Shao Miller

unread,
Sep 7, 2010, 7:06:21 PM9/7/10
to

"...computation of a value..." in 6.5 combined with your "unspecified"
above seems like good reasoning.

> The descriptions of & and | and << and >> also
> omit mention of padding bits, yet I'm confident there's no
> claim about what >>, say, does with padding in its operand.

Hmmm... The bitwise shift operators do mention "width"[6.5.7p3].
"Width" excludes padding bits[6.2.6.2p6], unless I'm mistaken. So
"there's no claim" amounts to "undefined behavior" which amounts to
"there's no claim". :)

>
> Back to ~, though: The reading you favor seems at odds with
> footnote 44, which describes the possible use of a padding bit
> as a parity bit. If the value bits and sign bit taken together
> come to an even number of bits and you invert them all, the
> parity of the whole remains unchanged. So if ~ also inverted
> a parity bit, the result would have bad parity -- and this would
> contradict the assertion that a valid arithmetic operation on a
> valid value cannot produce a trap representation. Footnotes are
> of course non-normative, but they offer a guide to how the writers
> expected the Standard to be understood.
>

Yes I mentioned the same concern about parity in an earlier post; seems
that we'd be in a pickle if unary '~' complemented parity bits which led
to a trap representation.

Speaking of non-normative footnotes, that footnote's sibling, footnote
45, causes me a bit of confusion. If we use '~' to produce a negative
zero and it's a trap representation, what kind of exceptional condition
is that?

Shao Miller

unread,
Sep 7, 2010, 7:14:55 PM9/7/10
to

Hmmm... Good point. If we cannot depend on the padding bits of the
result of an expression persisting into an object where the value is
stored, the information about the padding bits is gone.

>
>> If they _are_ defined to toggle, then that could very well be
>> behaviour that could come in handy... It limits what roles padding
>> bits can serve and we can derive expectations for the object
>> representations of the results of operations which can then be used to
>> determine characteristics of the environment. I'm not going to bet on
>> it.
>
> This bit seems very vague. What are these expectations and what might
> they enable us to determine about the environment?
>

Well since there aren't any padding bits in 'unsigned char' (and thus
the object representation), we can compare the object representations of
various numbers to find out what their differences are. This might
enable us to determine which of the three representations are being
used, or we might be able to find the sign bit. Or could we?

Shao Miller

unread,
Sep 7, 2010, 7:17:53 PM9/7/10
to
Keith Thompson wrote:
> Shao Miller <sha0....@gmail.com> writes:
>> Francois Grieu wrote:
> [snip]
>> Thank you very much for your response, Mr. F. Grieu. There is
>> definitely some food for thought in your post. Perhaps it's moot, as
>> you say.
>
> Just a thought: You could avoid any uncertainty about how to address
> people by not addressing them by name at all. For example, it's
> obvious from the attribution line who I'm addressing; there's no need
> to mention your name.
>
> I don't suggest that there's anything wrong with the way you're
> doing it, but it is a trifle unusual and I personally find that it
> distracts (*very* slightly) from the points you make.
>
> Feel free to ignore this.
>

I guess I just thought it was more personal in an expression of
appreciation, but thanks for the feedback. Perhaps that's a better
strategy.

Ben Bacarisse

unread,
Sep 7, 2010, 9:17:34 PM9/7/10
to
Shao Miller <sha0....@gmail.com> writes:

> Ben Bacarisse wrote:
<snip>


>> Shao Miller <sha0....@gmail.com> writes:
>>> If they _are_ defined to toggle, then that could very well be
>>> behaviour that could come in handy... It limits what roles padding
>>> bits can serve and we can derive expectations for the object
>>> representations of the results of operations which can then be used to
>>> determine characteristics of the environment. I'm not going to bet on
>>> it.
>>
>> This bit seems very vague. What are these expectations and what might
>> they enable us to determine about the environment?
>>
>
> Well since there aren't any padding bits in 'unsigned char' (and thus
> the object representation), we can compare the object representations
> of various numbers to find out what their differences are. This might
> enable us to determine which of the three representations are being
> used, or we might be able to find the sign bit. Or could we?

I don't see any connection to padding bits. You can determine the
number representation by inspecting the value of -1 & 3. It will 1, 2
or 3 depending on the use of sign+magnitude, ones complement or twos
complement respectively. However, like "endianness", wanting to know is
often a sign of a wrong turn having been taken in the design (not
always, but often).

--
Ben.

Ben Bacarisse

unread,
Sep 7, 2010, 9:38:32 PM9/7/10
to
Shao Miller <sha0....@gmail.com> writes:

It's a bit stronger than that. Promotion produces a value not a
representation. I would say that any promoted operand has no padding
bits at all.

> We do also have 6.3p2 regarding preservation of representation.
> Perhaps that could apply for those few cases where promotion causes no
> change in type. But that's now fewer cases, anyway.

I'd say the same even if the type does not change.

>>> The point is moot since the padding bit is a dodo,
>>> or a even a dahu AFAIK.
>>
>> As I keep saying, what about _Bool?
>
> And bit-fields, for that matter. If we have an 'int' bit-field, since
> there's no type change in promotion, I wonder if the other bits in the
> surrounding storage unit are preserved in the representation of the
> promoted result. What do you think?

My point is that promoted results don't have a representation.

At some level it doesn't matter either way. Imagine an implementation
that adds 107 padding bits to every promoted int. Since you can't
inspect these bits and they have no effect on the value, how could you
tell? I think it is simper to say they don't form part of the value
that results from a promotion.

But if it pleases you to think of them being there, why not? In fact,
lets just say that all padding bits stay with their values during
promotion and they all get toggled by ~. Now what? As far as I can
tell, such a language has the same semantics as the one I am describing.

>> I think the question is moot for another reason altogether. Even if ~
>> is absolutely forced to invert a "value" that somehow keeps the padding
>> bits, none of assignment, parameter passing nor initialisation are
>> required to preserve them so how can you tell? I take Shao Miller's
>> intent to be to find some way to inspect them and that requires that the
>> result of ~E finds itself, unchanged, inside some object or other.
>
> Yup. You're right on, and this would toss away inspection value
> unless 6.3p2 preserves padding bits in an assignment.

--
Ben.

pete

unread,
Sep 7, 2010, 9:54:47 PM9/7/10
to
Ben Bacarisse wrote:

> My point is that promoted results don't have a representation.

I disagree.

((((signed char)-1) + (signed char)0) & 3)

will still tell you which representation of negative integers
is used.

--
pete

Ben Bacarisse

unread,
Sep 7, 2010, 10:09:44 PM9/7/10
to
pete <pfi...@mindspring.com> writes:

Yes, what I wrote does not stand out of context. I should just have
said that promoted results don't have padding bits (though as I pointed
out this is just a simplification -- you can't tell if they do or do
not).

I think an argument can be made that values (such as promoted results)
don't have a representation but it would be verging on sophistry.

--
Ben.

Shao Miller

unread,
Sep 8, 2010, 1:02:33 AM9/8/10
to

Really? Surely the "the value is converted to an int" implies that the
representation for an 'int' applies, for example, including any
implementation-defined padding bits, doesn't it?

To suggest that we can have a value with a non-bit-field type but
without a consistent representation for the type (not the value) strikes
me as unusual with 3.14p1 and 3.17p1 in mind. In 6.5.16.1p4 we see
details of "...converted...to int width..." which, to me, suggests that
even intermediate, non-addressable values adhere to the type
representation (for non-bit-fields).

If you are suggesting that the padding bits of results are defined
inaccessibly except via object representation inspection, well that's
rather the nature of my line of questioning...

>
>> We do also have 6.3p2 regarding preservation of representation.
>> Perhaps that could apply for those few cases where promotion causes no
>> change in type. But that's now fewer cases, anyway.
>
> I'd say the same even if the type does not change.

The same meaning "theoretically, there are no padding bits associated
with the intermediate values during evaluation, because they are
inaccessible until inspected via object representation"?

> ... ... ...


> My point is that promoted results don't have a representation.
>

They can have a type but need not have a consistent type representation?

> At some level it doesn't matter either way. Imagine an implementation
> that adds 107 padding bits to every promoted int. Since you can't
> inspect these bits

That's really rather what I'm asking about. I apologize if it's not
clear. Please allow me to ask it differently: If we complement an 'int'
and store the result and inspect the object representation, are we
defined to discover that padding bits from the original have been
complemented in the stored result? I doubt it, but am uncertain.

> and they have no effect on the value, how could you
> tell? I think it is simper to say they don't form part of the value
> that results from a promotion.

Well I agree, they are a separate group of bits that also possibly
compose the type representation necessary for the value. But as for
inspection, see the question just above.

>
> But if it pleases you to think of them being there, why not? In fact,
> lets just say that all padding bits stay with their values during
> promotion and they all get toggled by ~. Now what? As far as I can
> tell, such a language has the same semantics as the one I am describing.
>

I think I understand your perspective; it's about accessibility of the
information regarding any possible padding bits. Since we work with
values and sign primarily, padding bits are pretty far out-of-scope for
theory. So really object representation inspection is the only area
where padding bits are in-scope. Since they're in-scope for this area,
I'd like to understand them better, and how useful information about
them is, perhaps in identification of environmental characteristics such
as parity representation or positional grouping of bits.

Thank you.

Ben Bacarisse

unread,
Sep 8, 2010, 9:58:45 AM9/8/10
to
[I will snip a lot because there seems to be only one issue here]
Shao Miller <sha0....@gmail.com> writes:

> Ben Bacarisse wrote:
<snip>


>> At some level it doesn't matter either way. Imagine an implementation
>> that adds 107 padding bits to every promoted int. Since you can't
>> inspect these bits
>
> That's really rather what I'm asking about. I apologize if it's not
> clear. Please allow me to ask it differently: If we complement an
> int' and store the result and inspect the object representation, are
> we defined to discover that padding bits from the original have been
> complemented in the stored result? I doubt it, but am uncertain.

It is certain that it can't be true in general (if, say, any padding bit
set to 1 represents a trap, then ~0 can't invert the padding bits) so
why bother speculating about some other cases?

I don't see any wording in the standard that says the padding bits are
ever predictable other than the words that say the trap representations
can't come about from safe arithmetic operations (and this includes ~).

For this reason, I prefer to think of the values that float about during
expression evaluation as being pure -- either pure binary with no
padding bits (but with a specific signed representation) or even as pure
mathematical values; the type with which they are associated being used
only to determine what words like "bit" means.

>> and they have no effect on the value, how could you
>> tell? I think it is simper to say they don't form part of the value
>> that results from a promotion.
>
> Well I agree, they are a separate group of bits that also possibly
> compose the type representation necessary for the value. But as for
> inspection, see the question just above.

By all means consider the value of ~0 to include any padding bits. What
you can't do is inspect them. What gets put into an object is *a*
representation of the value not *the* representation so you can't say
anything about them once they become amenable to inspection.

>> But if it pleases you to think of them being there, why not? In fact,
>> lets just say that all padding bits stay with their values during
>> promotion and they all get toggled by ~. Now what? As far as I can
>> tell, such a language has the same semantics as the one I am describing.
>
> I think I understand your perspective; it's about accessibility of the
> information regarding any possible padding bits. Since we work with
> values and sign primarily, padding bits are pretty far out-of-scope
> for theory. So really object representation inspection is the only
> area where padding bits are in-scope. Since they're in-scope for this
> area, I'd like to understand them better, and how useful information
> about them is, perhaps in identification of environmental
> characteristics such as parity representation or positional grouping
> of bits.

There are there for inspection in the object representation but since I
don't even think they need to be persistent I doubt there is much to be
gained from looking.

--
Ben.

Shao Miller

unread,
Sep 8, 2010, 11:09:07 AM9/8/10
to
Ben Bacarisse wrote:
> [I will snip a lot because there seems to be only one issue here]
> Shao Miller <sha0....@gmail.com> writes:
>
>> Ben Bacarisse wrote:
> <snip>
>>> At some level it doesn't matter either way. Imagine an implementation
>>> that adds 107 padding bits to every promoted int. Since you can't
>>> inspect these bits
>> That's really rather what I'm asking about. I apologize if it's not
>> clear. Please allow me to ask it differently: If we complement an
>> int' and store the result and inspect the object representation, are
>> we defined to discover that padding bits from the original have been
>> complemented in the stored result? I doubt it, but am uncertain.
>
> It is certain that it can't be true in general (if, say, any padding bit
> set to 1 represents a trap, then ~0 can't invert the padding bits) so
> why bother speculating about some other cases?

Aha. Perhaps an example might help.

Please consider the Hamming Code with N == 7, K == 4. There are three
parity checking bits. There are 2^K == 16 valid values with their
corresponding, parity-correct representations. But the number of
representations is 2^N == 128.

For each valid value, complementing the entire representation (including
parity bits) results in the correct representation (including parity
bits) for the complemented value bits; a case where complementing parity
makes perfect sense.

Each of the 128 - 16 == 112 remaining representations could be a trap
representation.

If our environment was specialized to be a system which pulls bytes from
a network, populates integer objects and performs mathematics on them,
we might desire this sort of scenario (albeit with greater N and K due
to the CHAR_BIT minimum, for instance).

Just the same as an invalid pointer value loaded into an address
register could be troublesome, perhaps we, the programmers, have the
opportunity to perform some integrity checks on the object
representation (via 'unsigned char') before we actually use the value
with some other integer type (which could effectively load a trap
representation into an arithmetic register and be troublesome).

So the sense that I'm getting from some responses here is not that the C
Standard limits integer representations at all. Otherwise, unary '~'
complementing each bit in an operand could be perceived as something of
a constraint on representations in that whatever the uses (if any) of
padding bits are, they must be consistent with complementing.

>
> I don't see any wording in the standard that says the padding bits are
> ever predictable other than the words that say the trap representations
> can't come about from safe arithmetic operations (and this includes ~).

Yeahbut that's what I'm asking. 6.5.3.3p4 says "operand" rather than
"value". That's wording which could be interpreted to include padding
bits. The fact that we shall not produce a trap representation other
than as part of an exceptional condition could be viewed as a constraint
on what padding bits are used for.

>
> For this reason, I prefer to think of the values that float about during
> expression evaluation as being pure -- either pure binary with no
> padding bits (but with a specific signed representation) or even as pure
> mathematical values; the type with which they are associated being used
> only to determine what words like "bit" means.

Ok.

>
>>> and they have no effect on the value, how could you
>>> tell? I think it is simper to say they don't form part of the value
>>> that results from a promotion.
>> Well I agree, they are a separate group of bits that also possibly
>> compose the type representation necessary for the value. But as for
>> inspection, see the question just above.
>
> By all means consider the value of ~0 to include any padding bits. What
> you can't do is inspect them. What gets put into an object is *a*
> representation of the value not *the* representation so you can't say
> anything about them once they become amenable to inspection.

So your stance here is that in 'x = ~x;', we have the read of 'x' result
in an abstract mathematical value, the value bits are complemented, then
those bits are stored back into 'x' along with theoretically random
padding bits, which have theoretically zero state correlation to the
padding bits in the previous object representation for 'x'. Is that right?

>
>>> But if it pleases you to think of them being there, why not? In fact,
>>> lets just say that all padding bits stay with their values during
>>> promotion and they all get toggled by ~. Now what? As far as I can
>>> tell, such a language has the same semantics as the one I am describing.
>> I think I understand your perspective; it's about accessibility of the
>> information regarding any possible padding bits. Since we work with
>> values and sign primarily, padding bits are pretty far out-of-scope
>> for theory. So really object representation inspection is the only
>> area where padding bits are in-scope. Since they're in-scope for this
>> area, I'd like to understand them better, and how useful information
>> about them is, perhaps in identification of environmental
>> characteristics such as parity representation or positional grouping
>> of bits.
>
> There are there for inspection in the object representation but since I
> don't even think they need to be persistent I doubt there is much to be
> gained from looking.
>

Persistence! That is an excellent point! If I copy the object
representation of a 'struct' which includes padding and immediately
thereafter compare the object representations of the original and the
copy, am I guaranteed to find that padding bits are the same? I should
think so, given that 'unsigned char' has no padding bits.

When 6.2.4p2 says "last-stored value", would it be a tad more accurate
to state that an object retains its "last-stored object representation",
instead? Otherwise, I'm imagining padding bits being allowed to
flip-flop at random on a conforming implementation. After all, it's not
until we access as a character type that the object could be considered
to have no padding bits.

Thanks again!

Ben Bacarisse

unread,
Sep 8, 2010, 1:11:04 PM9/8/10
to
Shao Miller <sha0....@gmail.com> writes:

> Ben Bacarisse wrote:
>> [I will snip a lot because there seems to be only one issue here]
>> Shao Miller <sha0....@gmail.com> writes:
>>
>>> Ben Bacarisse wrote:
>> <snip>
>>>> At some level it doesn't matter either way. Imagine an implementation
>>>> that adds 107 padding bits to every promoted int. Since you can't
>>>> inspect these bits
>>> That's really rather what I'm asking about. I apologize if it's not
>>> clear. Please allow me to ask it differently: If we complement an
>>> int' and store the result and inspect the object representation, are
>>> we defined to discover that padding bits from the original have been
>>> complemented in the stored result? I doubt it, but am uncertain.
>>
>> It is certain that it can't be true in general (if, say, any padding bit
>> set to 1 represents a trap, then ~0 can't invert the padding bits) so
>> why bother speculating about some other cases?
>
> Aha. Perhaps an example might help.

I don't think so. An example of how unspecified behaviour might be
implemented does not address the question. C certainly permits an
implementation to preserve or to manipulate the padding bits is almost
any way so there will be examples where useful things will happen. In
general, you can't rely on what the padding bits end up holding but I
have no problem with an implementation that says a lot more.

My argument that values don't have padding bits is just an abstract view
of how I think it helps to look at portable C which was, I think, the
original context. Some implementations may be a lot more specific but
that's a lot less interesting.

<snip>


>> I don't see any wording in the standard that says the padding bits are
>> ever predictable other than the words that say the trap representations
>> can't come about from safe arithmetic operations (and this includes ~).
>
> Yeahbut that's what I'm asking. 6.5.3.3p4 says "operand" rather than
> "value". That's wording which could be interpreted to include padding
> bits. The fact that we shall not produce a trap representation other
> than as part of an exceptional condition could be viewed as a
> constraint on what padding bits are used for.

If you want to read it that way. I don't have any enthusiasm for an
argument about what an operand is -- its clear we don't agree about many
of the plain terms of the standard. But no matter, you are half way
there. Because the standard says "(promoted) operand" rather than
"value" all you now need is some wording that lets you be convinced that
this representation has to get back into an object unchanged and you
will have the assurance you are looking for. Since padding bits in ints
(the usual promoted type for ~) are rare you won't have much trouble
with implementations that don't conform because they took another
reading of the standard.

>> For this reason, I prefer to think of the values that float about during
>> expression evaluation as being pure -- either pure binary with no
>> padding bits (but with a specific signed representation) or even as pure
>> mathematical values; the type with which they are associated being used
>> only to determine what words like "bit" means.
>
> Ok.
>
>>
>>>> and they have no effect on the value, how could you
>>>> tell? I think it is simper to say they don't form part of the value
>>>> that results from a promotion.
>>> Well I agree, they are a separate group of bits that also possibly
>>> compose the type representation necessary for the value. But as for
>>> inspection, see the question just above.
>>
>> By all means consider the value of ~0 to include any padding bits. What
>> you can't do is inspect them. What gets put into an object is *a*
>> representation of the value not *the* representation so you can't say
>> anything about them once they become amenable to inspection.
>
> So your stance here is that in 'x = ~x;', we have the read of 'x'
> result in an abstract mathematical value, the value bits are
> complemented, then those bits are stored back into 'x' along with
> theoretically random padding bits, which have theoretically zero state
> correlation to the padding bits in the previous object representation
> for 'x'. Is that right?

In the general case, yes. In other words, your paraphrasing is the most
one be assured of. Some implementations may be far more specific and
won't then fit with the view I've presented. That, to me is the right
way round in that I am happier to permit specific exceptions to a
general rule that to have a specific rule that I have to keep reminding
myself does not apply in general.

<snip>


>> There are there for inspection in the object representation but since I
>> don't even think they need to be persistent I doubt there is much to be
>> gained from looking.
>>
>
> Persistence! That is an excellent point! If I copy the object
> representation of a 'struct' which includes padding and immediately
> thereafter compare the object representations of the original and the
> copy, am I guaranteed to find that padding bits are the same? I
> should think so, given that 'unsigned char' has no padding bits.

Why can't the padding in the struct change its setting between the copy
and the compare?

> When 6.2.4p2 says "last-stored value", would it be a tad more accurate
> to state that an object retains its "last-stored object
> representation", instead?

If that was intended meaning, yes. Do you know if that was the intent
or did the committee mean exactly what they wrote?

Since I have no interest in writing a program where the distinction
matters, I am happy with either meaning; and if I ever have to write
such a program I'll take the interpretation that gives me the least
guarantees just to be on the safe side.

> Otherwise, I'm imagining padding bits being
> allowed to flip-flop at random on a conforming implementation. After
> all, it's not until we access as a character type that the object
> could be considered to have no padding bits.

That's my view of them. In order to steer clear of portability problems
I imagine an abstract C machine with the worst possible behaviour that I
think is still permitted by the standard. I've never written a program
that cares if the padding bits "stick" or not so this view of them is
pretty unlikely to matter to me but I can't be sure that they do retain
their settings, so until someone persuades me that objects hold their
last stored *representation* I'll stick with it.

--
Ben.

Shao Miller

unread,
Sep 8, 2010, 2:05:29 PM9/8/10
to
On Sep 8, 1:11 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:

> Shao Miller <sha0.mil...@gmail.com> writes:
> > Ben Bacarisse wrote:
> >> [I will snip a lot because there seems to be only one issue here]
> >> Shao Miller <sha0.mil...@gmail.com> writes:
>
> >>> Ben Bacarisse wrote:
> >> <snip>
> >>>> At some level it doesn't matter either way.  Imagine an implementation
> >>>> that adds 107 padding bits to every promoted int.  Since you can't
> >>>> inspect these bits
> >>> That's really rather what I'm asking about.  I apologize if it's not
> >>> clear.  Please allow me to ask it differently: If we complement an
> >>> int' and store the result and inspect the object representation, are
> >>> we defined to discover that padding bits from the original have been
> >>> complemented in the stored result?  I doubt it, but am uncertain.
>
> >> It is certain that it can't be true in general (if, say, any padding bit
> >> set to 1 represents a trap, then ~0 can't invert the padding bits) so
> >> why bother speculating about some other cases?
>
> > Aha.  Perhaps an example might help.
>
> I don't think so.  An example of how unspecified behaviour might be
> implemented does not address the question.  C certainly permits an
> implementation to preserve or to manipulate the padding bits is almost
> any way so there will be examples where useful things will happen.  In
> general, you can't rely on what the padding bits end up holding but I
> have no problem with an implementation that says a lot more.

If the wording of the Standard can reasonably be debated (reasonably
being subjective to participants and observers), then an example like
I gave could help to clarify my question, not to answer it. I'm
asking about the effect of unary '~' on padding bits because I'm
trying to understand what the Standard offers implementations and
programmers in regards to them. If we didn't write the Standard, then
we can either speculate on what reasoning led to the wording, or we
can find a definitive answer. Have we seen a definitive answer? If
not, my question can only be answered with advice for best practices
and speculation. My "snipped" example merely tries to help me to ask,
"Could the wording mean FOO and have stemmed from considerations such
as BAR?"

>
> My argument that values don't have padding bits is just an abstract view
> of how I think it helps to look at portable C which was, I think, the
> original context.  Some implementations may be a lot more specific but
> that's a lot less interesting.
>

If it ever turns out (which it mightn't) that padding bits are defined
to be complemented by unary '~', then that knowledge might be useful.
I genuinely appreciate your abstract view that you have shared. Where
you say that some implementations might be a lot more specific but a
lot less interesting, this I can disagree to. A portable program
which is capable of determining characteristics of the implementation/
environment through a battery of tests seems like it might be handy,
and this is part of the intentions behind the questions. Where the
Standard doesn't mandate that implementation-defined choices be
accessible in a portable fashion, how can we best find out about these
choices in efforts to produce portable programs? Mr. T. Rentsch's
integer limits code that he kindly shared recently are a really
enjoyable example.

> <snip>
>
> >> I don't see any wording in the standard that says the padding bits are
> >> ever predictable other than the words that say the trap representations
> >> can't come about from safe arithmetic operations (and this includes ~).
>
> > Yeahbut that's what I'm asking.  6.5.3.3p4 says "operand" rather than
> > "value".  That's wording which could be interpreted to include padding
> > bits.  The fact that we shall not produce a trap representation other
> > than as part of an exceptional condition could be viewed as a
> > constraint on what padding bits are used for.
>
> If you want to read it that way.  I don't have any enthusiasm for an
> argument about what an operand is

Ok.

> -- its clear we don't agree about many
> of the plain terms of the standard.

Why does this have to get personal? It doesn't. I don't know of any
terms at all that we disagree about. Perhaps I have communicated
poorly and my questions have been perceived as claims? If so, then I
apologize. Otherwise, I'd really rather agree than disagree. It
makes any discussion about our shared interest that much more
meaningful. :)

> But no matter, you are half way
> there.  Because the standard says "(promoted) operand" rather than
> "value" all you now need is some wording that lets you be convinced that
> this representation has to get back into an object unchanged and you
> will have the assurance you are looking for.

Whoa, whoa. I'm not looking for assurance that padding bits are
complemented. I'm inclined as you are to play it safe. I'm looking
for assurance that they either are defined to or are not defined to.

> Since padding bits in ints
> (the usual promoted type for ~) are rare you won't have much trouble
> with implementations that don't conform because they took another
> reading of the standard.
>

Absolutely.

>
> ... ... ...


> > So your stance here is that in 'x = ~x;', we have the read of 'x'
> > result in an abstract mathematical value, the value bits are
> > complemented, then those bits are stored back into 'x' along with
> > theoretically random padding bits, which have theoretically zero state
> > correlation to the padding bits in the previous object representation
> > for 'x'.  Is that right?
>
> In the general case, yes.  In other words, your paraphrasing is the most
> one be assured of.  Some implementations may be far more specific and
> won't then fit with the view I've presented.  That, to me is the right
> way round in that I am happier to permit specific exceptions to a
> general rule that to have a specific rule that I have to keep reminding
> myself does not apply in general.
>

Ok. Thanks. You have been asked for your interpretation and you have
given it along with good advice.

>
> >> There are there for inspection in the object representation but since I
> >> don't even think they need to be persistent I doubt there is much to be
> >> gained from looking.
>
> > Persistence!  That is an excellent point!  If I copy the object
> > representation of a 'struct' which includes padding and immediately
> > thereafter compare the object representations of the original and the
> > copy, am I guaranteed to find that padding bits are the same?  I
> > should think so, given that 'unsigned char' has no padding bits.
>
> Why can't the padding in the struct change its setting between the copy
> and the compare?

Why are you asking me when I'm asking you? I don't know the answer
and hoped that you or another reader might. I did suggest that
'unsigned char' has no padding bits, so for "last-stored value" to be
true, we must preserve all bits even if we are going to interpret them
at some point via a type which includes padding. What do you think?

>
> > When 6.2.4p2 says "last-stored value", would it be a tad more accurate
> > to state that an object retains its "last-stored object
> > representation", instead?
>
> If that was intended meaning, yes.  Do you know if that was the intent
> or did the committee mean exactly what they wrote?
>

I do not know if that was the intent at all. What do you think?
Maybe someone who knows the author's/authors' intentions could help to
answer?

> Since I have no interest in writing a program where the distinction
> matters, I am happy with either meaning; and if I ever have to write
> such a program I'll take the interpretation that gives me the least
> guarantees just to be on the safe side.
>

Absolutely. :)

> >  Otherwise, I'm imagining padding bits being
> > allowed to flip-flop at random on a conforming implementation.  After
> > all, it's not until we access as a character type that the object
> > could be considered to have no padding bits.
>
> That's my view of them.  In order to steer clear of portability problems
> I imagine an abstract C machine with the worst possible behaviour that I
> think is still permitted by the standard.  I've never written a program
> that cares if the padding bits "stick" or not so this view of them is
> pretty unlikely to matter to me but I can't be sure that they do retain
> their settings, so until someone persuades me that objects hold their
> last stored *representation* I'll stick with it.

Ok. So this particular scenario of copying object representations and
comparing has not been particularly practical, in your experience.

lawrenc...@siemens.com

unread,
Sep 8, 2010, 12:30:54 PM9/8/10
to
Shao Miller <sha0....@gmail.com> wrote:
>
> Speaking of non-normative footnotes, that footnote's sibling, footnote
> 45, causes me a bit of confusion. If we use '~' to produce a negative
> zero and it's a trap representation, what kind of exceptional condition
> is that?

Applying the ~ operator to an operand that produces such a value, which is
explicitly undefined behavior.
--
Larry Jones

I like maxims that don't encourage behavior modification. -- Calvin

lawrenc...@siemens.com

unread,
Sep 8, 2010, 12:26:28 PM9/8/10
to
Shao Miller <sha0....@gmail.com> wrote:
>
> That's really rather what I'm asking about. I apologize if it's not
> clear. Please allow me to ask it differently: If we complement an 'int'
> and store the result and inspect the object representation, are we
> defined to discover that padding bits from the original have been
> complemented in the stored result?

No. *All* operators operate on values, not object representations, and
padding bits (by definition) are not part of the value. Their settings
are always unspecified.
--
Larry Jones

Well, it's all a question of perspective. -- Calvin

Shao Miller

unread,
Sep 8, 2010, 2:29:44 PM9/8/10
to
On Sep 8, 12:30 pm, lawrence.jo...@siemens.com wrote:

> Shao Miller <sha0.mil...@gmail.com> wrote:
>
> > Speaking of non-normative footnotes, that footnote's sibling, footnote
> > 45, causes me a bit of confusion.  If we use '~' to produce a negative
> > zero and it's a trap representation, what kind of exceptional condition
> > is that?
>
> Applying the ~ operator to an operand that produces such a value, which is
> explicitly undefined behavior.

Excellent, as always. Then I can add to a list of exceptional
conditions and take it that we have to be extra careful about, say,
'~32767' for a 16-bit 'int' with sign-and-magnitude representation,
since we might get undefined behaviour. Fair enough! :) Thank you.

Shao Miller

unread,
Sep 8, 2010, 2:41:15 PM9/8/10
to
On Sep 8, 12:26 pm, lawrence.jo...@siemens.com wrote:

> Shao Miller <sha0.mil...@gmail.com> wrote:
>
> > That's really rather what I'm asking about.  I apologize if it's not
> > clear.  Please allow me to ask it differently: If we complement an 'int'
> > and store the result and inspect the object representation, are we
> > defined to discover that padding bits from the original have been
> > complemented in the stored result?
>
> No.  *All* operators operate on values, not object representations, and
> padding bits (by definition) are not part of the value.  Their settings
> are always unspecified.

Very well. This is completely consistent with Ben's notion of an
abstract mathematical value without representation. Quick question:
After a copy of something including unspecified padding bits via
'unsigned char', can we expect that the bits in the copy match the
bits of the original if we compare via 'unsigned char'? Or does the
type of the original allow for the padding bits in the copy to be
theoretically random even during the copy; even if byte comparison is
the very first thing we do before using the copy via the type of the
original? Thank you.

lawrenc...@siemens.com

unread,
Sep 8, 2010, 3:12:31 PM9/8/10
to
Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>
> Why can't the padding in the struct change its setting between the copy
> and the compare?

Because the bytes that compose the struct are themselves objects (that
don't have padding bits) and thus subject to the "objects retain their
last stored value" guarantee.
--
Larry Jones

Pitiful. Just pitiful. -- Calvin

Shao Miller

unread,
Sep 8, 2010, 6:32:56 PM9/8/10
to

I see that you answered this quick question in another post. You stated
that "...the bytes that compose the struct are themselves objects (that
don't have padding bits) and thus...retain their last stored value..."
(please forgive the exclusions).

In this case, could "last-stored object representation" lead to this
conclusion perhaps more directly for a reader? Because the C1X draft
has "come to the rescue" three times already in my recollection, I did
check it out before asking. :)

Also, I think it might be worth noting that I think your "*All*" might
require the context of arithmetic operators... 'sizeof' doesn't strike
me as operating on a value, neither does a redundant cast to 'void', nor
a ternary conditional operator with two void expressions as second and
third operands, nor a comma operator with void expressions as operands,
nor 'alignof' in C1X. I've no idea if '_Generic()' in C1X should be
called a proper operator or not.

But anyway, it's good to know that unary '~' is not defined to have any
influence on padding bits anywhere, as per the majority of responses
here... I'll just wish that it was a little more directly evident...
C1X 6.5p4 describes values with types and representations, and that
includes padding bits, to me.

Thanks again.

Ben Bacarisse

unread,
Sep 8, 2010, 7:07:20 PM9/8/10
to
Shao Miller <sha0....@gmail.com> writes:

I don't think I've misunderstood your question. The example certainly
did not make me look at the question in a new light. Maybe I missed the
point.

> I'm
> asking about the effect of unary '~' on padding bits because I'm
> trying to understand what the Standard offers implementations and
> programmers in regards to them. If we didn't write the Standard, then
> we can either speculate on what reasoning led to the wording, or we
> can find a definitive answer. Have we seen a definitive answer?

There is no "we" in this regard. You have to answer for yourself.
Presumably nothing anyone has said has so far seemed definitive.

> If
> not, my question can only be answered with advice for best practices
> and speculation. My "snipped" example merely tries to help me to ask,
> "Could the wording mean FOO and have stemmed from considerations such
> as BAR?"

Had you asked that, I would have had a go at answering it, but it seemed
to be simply a case where parity was preserved under complement. I
can't see how that sheds any light on the matter. Almost everything to
about padding bits is unspecified so as to permit this along with dozens
of other schemes.

>> My argument that values don't have padding bits is just an abstract view
>> of how I think it helps to look at portable C which was, I think, the
>> original context.  Some implementations may be a lot more specific but
>> that's a lot less interesting.
>
> If it ever turns out (which it mightn't) that padding bits are defined
> to be complemented by unary '~', then that knowledge might be useful.
> I genuinely appreciate your abstract view that you have shared. Where
> you say that some implementations might be a lot more specific but a
> lot less interesting, this I can disagree to. A portable program
> which is capable of determining characteristics of the implementation/
> environment through a battery of tests seems like it might be handy,
> and this is part of the intentions behind the questions.

Programming is ultimate a practical endeavour -- please give an example.
What might you like to find out with a portable program? How might the
answer help or be otherwise useful? With a real practical goal, you
might find more people willing to join in.

> Where the
> Standard doesn't mandate that implementation-defined choices be
> accessible in a portable fashion, how can we best find out about these
> choices in efforts to produce portable programs? Mr. T. Rentsch's
> integer limits code that he kindly shared recently are a really
> enjoyable example.

Agreed. What similarly practical problem has led to this question about
padding bits and the ~ operator?

>> <snip>
>>
>> >> I don't see any wording in the standard that says the padding bits are
>> >> ever predictable other than the words that say the trap representations
>> >> can't come about from safe arithmetic operations (and this includes ~).
>>
>> > Yeahbut that's what I'm asking.  6.5.3.3p4 says "operand" rather than
>> > "value".  That's wording which could be interpreted to include padding
>> > bits.  The fact that we shall not produce a trap representation other
>> > than as part of an exceptional condition could be viewed as a
>> > constraint on what padding bits are used for.
>>
>> If you want to read it that way.  I don't have any enthusiasm for an
>> argument about what an operand is
>
> Ok.
>
>> -- its clear we don't agree about many
>> of the plain terms of the standard.
>
> Why does this have to get personal?

What's personal about that? I may be wrong, but it is not a personal
remark.

> It doesn't. I don't know of any
> terms at all that we disagree about.

Operand, value and result spring to mind. Maybe we are now in agreement
about "result" but I don't recall any clear resolution. You would not
say "6.5.3.3p4 says 'operand' rather than 'value'" if we agreed on those
two terms. The last time a similar case cropped up (whether a result
can be a type devoid of any associated value) it went on far longer that
it should have. I intend to do better in future!

> Perhaps I have communicated
> poorly and my questions have been perceived as claims? If so, then I
> apologize. Otherwise, I'd really rather agree than disagree. It
> makes any discussion about our shared interest that much more
> meaningful. :)
>
>> But no matter, you are half way
>> there.  Because the standard says "(promoted) operand" rather than
>> "value" all you now need is some wording that lets you be convinced that
>> this representation has to get back into an object unchanged and you
>> will have the assurance you are looking for.
>
> Whoa, whoa. I'm not looking for assurance that padding bits are
> complemented. I'm inclined as you are to play it safe. I'm looking
> for assurance that they either are defined to or are not defined to.

Let's put aside the issue of whether the padding bits are even there in
the promoted result and assume that they are (I don't agree but lets go
there for the moment). I gave an example where they must not be
inverted by the ~ operator -- where any padding bit other than 0 is a
trap representation. From this I think one must conclude that there
could not a requirement that they be complemented.

<snip>


>> >> There are there for inspection in the object representation but since I
>> >> don't even think they need to be persistent I doubt there is much to be
>> >> gained from looking.
>>
>> > Persistence!  That is an excellent point!  If I copy the object
>> > representation of a 'struct' which includes padding and immediately
>> > thereafter compare the object representations of the original and the
>> > copy, am I guaranteed to find that padding bits are the same?  I
>> > should think so, given that 'unsigned char' has no padding bits.
>>
>> Why can't the padding in the struct change its setting between the copy
>> and the compare?
>
> Why are you asking me when I'm asking you?

Because I disagreed and wanted to point to what I thought was the key
issue, but I am not so sure anymore.

I think you are right if there is access via a character-typed lvalue
expression. That's not always the case in the copying scenario you
describe but since the smallest change to the program would require the
whole structure to be stable it seems inconceivable that any
implementation would distinguish between the two situations.

There are things to worry about, there are things not to worry about and
then there is this!

<snip>
--
Ben.

Ben Bacarisse

unread,
Sep 8, 2010, 7:58:22 PM9/8/10
to
lawrenc...@siemens.com writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>>
>> Why can't the padding in the struct change its setting between the copy
>> and the compare?
>
> Because the bytes that compose the struct are themselves objects (that
> don't have padding bits) and thus subject to the "objects retain their
> last stored value" guarantee.

That surprises me (but only a little) because of 6.2.6.1 p6. These are
component objects that retain their last stored value but which may
change value when other (possibly distant) parts of the larger object
have *their* stored value changed.

BTW, I now think my original claim is wrong but I am still a little
puzzled by what constitutes the "last stored value" for a padding byte
in a struct.

--
Ben.

Shao Miller

unread,
Sep 9, 2010, 3:13:02 AM9/9/10
to
Ben Bacarisse wrote:
> Shao Miller <sha0....@gmail.com> writes:
>
>> On Sep 8, 1:11 pm, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>>> Shao Miller <sha0.mil...@gmail.com> writes:
>>>> Ben Bacarisse wrote:
>>>>> [I will snip a lot because there seems to be only one issue here]
>>>>> Shao Miller <sha0.mil...@gmail.com> writes:
>>>>>> Ben Bacarisse wrote:
>>>>> <snip>
> ... ... ...

> I don't think I've misunderstood your question. The example certainly
> did not make me look at the question in a new light. Maybe I missed the
> point.
>

If you did, that's a failure on my part to communicate.

>> I'm
>> asking about the effect of unary '~' on padding bits because I'm
>> trying to understand what the Standard offers implementations and
>> programmers in regards to them. If we didn't write the Standard, then
>> we can either speculate on what reasoning led to the wording, or we
>> can find a definitive answer. Have we seen a definitive answer?
>
> There is no "we" in this regard. You have to answer for yourself.
> Presumably nothing anyone has said has so far seemed definitive.
>

I'm thinking that something along the lines of:

A: Note section BAZ, point WHEE: "It is unspecified whether computations
of a value affect padding bits or not."

might be a definitive answer. I'd hope that "we" could agree to such,
if A piped-in with that.

>> If
>> not, my question can only be answered with advice for best practices
>> and speculation. My "snipped" example merely tries to help me to ask,
>> "Could the wording mean FOO and have stemmed from considerations such
>> as BAR?"
>
> Had you asked that, I would have had a go at answering it, but it seemed
> to be simply a case where parity was preserved under complement. I
> can't see how that sheds any light on the matter. Almost everything to
> about padding bits is unspecified so as to permit this along with dozens
> of other schemes.
>

Thanks. That makes sense. Then perhaps the authors did not intend to
limit the uses of padding bits and did not intend to constrain integer
representations beyond the three value formats in signed representations.

>>> My argument that values don't have padding bits is just an abstract view
>>> of how I think it helps to look at portable C which was, I think, the
>>> original context. Some implementations may be a lot more specific but
>>> that's a lot less interesting.
>> If it ever turns out (which it mightn't) that padding bits are defined
>> to be complemented by unary '~', then that knowledge might be useful.
>> I genuinely appreciate your abstract view that you have shared. Where
>> you say that some implementations might be a lot more specific but a
>> lot less interesting, this I can disagree to. A portable program
>> which is capable of determining characteristics of the implementation/
>> environment through a battery of tests seems like it might be handy,
>> and this is part of the intentions behind the questions.
>
> Programming is ultimate a practical endeavour -- please give an example.
> What might you like to find out with a portable program? How might the
> answer help or be otherwise useful? With a real practical goal, you
> might find more people willing to join in.

Good point and I will keep that in mind. Perhaps you are correct and
more people will be inclined to discuss possibly practical code rather
than Standard theory. Very well.

>
>> Where the
>> Standard doesn't mandate that implementation-defined choices be
>> accessible in a portable fashion, how can we best find out about these
>> choices in efforts to produce portable programs? Mr. T. Rentsch's
>> integer limits code that he kindly shared recently are a really
>> enjoyable example.
>
> Agreed. What similarly practical problem has led to this question about
> padding bits and the ~ operator?
>

Reporting to a programmer which trap representations are suspected for
the environment. If and only if padding bits are guaranteed to
complement, this limits what padding bits can be used for, and as we
compare object representations to known representations, we needn't
consider known representations where padding bits do not complement;
they wouldn't be allowed for conformance.

>>> <snip>
>>>
>>>>> I don't see any wording in the standard that says the padding bits are
>>>>> ever predictable other than the words that say the trap representations
>>>>> can't come about from safe arithmetic operations (and this includes ~).
>>>> Yeahbut that's what I'm asking. 6.5.3.3p4 says "operand" rather than
>>>> "value". That's wording which could be interpreted to include padding
>>>> bits. The fact that we shall not produce a trap representation other
>>>> than as part of an exceptional condition could be viewed as a
>>>> constraint on what padding bits are used for.
>>> If you want to read it that way. I don't have any enthusiasm for an
>>> argument about what an operand is
>> Ok.
>>
>>> -- its clear we don't agree about many
>>> of the plain terms of the standard.
>> Why does this have to get personal?
>
> What's personal about that? I may be wrong, but it is not a personal
> remark.
>

I misunderstood, then. Sorry.

>> It doesn't. I don't know of any
>> terms at all that we disagree about.
>
> Operand, value and result spring to mind. Maybe we are now in agreement
> about "result" but I don't recall any clear resolution. You would not
> say "6.5.3.3p4 says 'operand' rather than 'value'" if we agreed on those
> two terms. The last time a similar case cropped up (whether a result
> can be a type devoid of any associated value) it went on far longer that
> it should have. I intend to do better in future!
>

"Operand" is 6.4.6p2. "Value" is 3.17p1 in 'n1256.pdf' and 3.19p1 in
C1X. I am not familiar with a C Standard definition for "result", not
sure one is possible, and not sure one is needed; a dictionary
definition might suffice. I think we can reasonably understand "result"
to be an accumulation of defined properties and predicate-truths.

But you're absolutely right: Let's not go there. :)

>> Perhaps I have communicated
>> poorly and my questions have been perceived as claims? If so, then I
>> apologize. Otherwise, I'd really rather agree than disagree. It
>> makes any discussion about our shared interest that much more
>> meaningful. :)
>>
>>> But no matter, you are half way
>>> there. Because the standard says "(promoted) operand" rather than
>>> "value" all you now need is some wording that lets you be convinced that
>>> this representation has to get back into an object unchanged and you
>>> will have the assurance you are looking for.
>> Whoa, whoa. I'm not looking for assurance that padding bits are
>> complemented. I'm inclined as you are to play it safe. I'm looking
>> for assurance that they either are defined to or are not defined to.
>
> Let's put aside the issue of whether the padding bits are even there in
> the promoted result and assume that they are (I don't agree but lets go
> there for the moment). I gave an example where they must not be
> inverted by the ~ operator -- where any padding bit other than 0 is a
> trap representation. From this I think one must conclude that there
> could not a requirement that they be complemented.

I agree with this. It's certainly one way or the other: Either the
Standard constrains what padding bits can be used for (beyond that we
know they contribute to neither sign nor value) or it doesn't. If it
doesn't, then the situation you describe would require that unary '~'
does not complement all bits in a result.

> ... ... ...


>>> Why can't the padding in the struct change its setting between the copy
>>> and the compare?
>> Why are you asking me when I'm asking you?

> ... ... ...


> There are things to worry about, there are things not to worry about and
> then there is this!

Ok.

Ben Bacarisse

unread,
Sep 9, 2010, 10:35:42 AM9/9/10
to
Shao Miller <sha0....@gmail.com> writes:

> Ben Bacarisse wrote:
>> Shao Miller <sha0....@gmail.com> writes:

<snip>
>>> [...] My "snipped" example merely tries to help me to ask,


>>> "Could the wording mean FOO and have stemmed from considerations such
>>> as BAR?"
>>
>> Had you asked that, I would have had a go at answering it, but it seemed
>> to be simply a case where parity was preserved under complement. I
>> can't see how that sheds any light on the matter. Almost everything to
>> about padding bits is unspecified so as to permit this along with dozens
>> of other schemes.
>>
>
> Thanks. That makes sense. Then perhaps the authors did not intend to
> limit the uses of padding bits and did not intend to constrain integer
> representations beyond the three value formats in signed
> representations.

I'd agree if you dropped the "Then...". Perhaps the authors intended
all sorts of other things (it's always possible) but in no way does your
second suggestion follow from your agreement with me.

<snip>


>> Let's put aside the issue of whether the padding bits are even there in
>> the promoted result and assume that they are (I don't agree but lets go
>> there for the moment). I gave an example where they must not be
>> inverted by the ~ operator -- where any padding bit other than 0 is a
>> trap representation. From this I think one must conclude that there
>> could not a requirement that they be complemented.
>
> I agree with this. It's certainly one way or the other: Either the
> Standard constrains what padding bits can be used for (beyond that we
> know they contribute to neither sign nor value) or it doesn't. If it
> doesn't, then the situation you describe would require that unary '~'
> does not complement all bits in a result.

Odd. You agree and then write something different. I am glad you agree
but I am not 100% sure what you agree with.

<snip>
--
Ben.

Shao Miller

unread,
Sep 9, 2010, 2:46:17 PM9/9/10
to
Ben Bacarisse wrote:
> Shao Miller <sha0....@gmail.com> writes:
>
>> Ben Bacarisse wrote:
>>> Shao Miller <sha0....@gmail.com> writes:
> <snip>
>>>> [...] My "snipped" example merely tries to help me to ask,
>>>> "Could the wording mean FOO and have stemmed from considerations such
>>>> as BAR?"
>>> Had you asked that, I would have had a go at answering it, but it seemed
>>> to be simply a case where parity was preserved under complement. I
>>> can't see how that sheds any light on the matter. Almost everything to
>>> about padding bits is unspecified so as to permit this along with dozens
>>> of other schemes.
>>>
>> Thanks. That makes sense. Then perhaps the authors did not intend to
>> limit the uses of padding bits and did not intend to constrain integer
>> representations beyond the three value formats in signed
>> representations.
>
> I'd agree if you dropped the "Then...". Perhaps the authors intended
> all sorts of other things (it's always possible) but in no way does your
> second suggestion follow from your agreement with me.

"Almost everything to [do with] padding bits is unspecified so as to
permit this along with dozens of other schemes." <-> "Then perhaps the
authors did not intend to limit the uses of padding bits..." Permit.
Did not intend to limit.

>
> <snip>
>>> Let's put aside the issue of whether the padding bits are even there in
>>> the promoted result and assume that they are (I don't agree but lets go
>>> there for the moment). I gave an example where they must not be
>>> inverted by the ~ operator -- where any padding bit other than 0 is a
>>> trap representation. From this I think one must conclude that there
>>> could not a requirement that they be complemented.
>> I agree with this. It's certainly one way or the other: Either the
>> Standard constrains what padding bits can be used for (beyond that we
>> know they contribute to neither sign nor value) or it doesn't. If it
>> doesn't, then the situation you describe would require that unary '~'
>> does not complement all bits in a result.
>
> Odd. You agree and then write something different. I am glad you agree
> but I am not 100% sure what you agree with.

It's simple. In my first response to Mr. E. Sosman, I noted this very
example but didn't completely reference it. In 'n1256.pdf', the example
is present in footnotes 44 and 45.

"I did see an example in the C1X draft where a padding bit might be a
parity bit. My impression was that the bit _might_ be complemented
during the bitwise '~', but only as a matter of co-incidence, and not
because '~' is defined to complement padding bits. Would you agree to
that?"

As Mr. Sosman said, if we accept that 6.2.6.2's padding bits being
"unspecified" takes precedence above anything else (such as an operand
value having a type and the operand beyond its value being subject to a
type representation including padding bits), then that's that. 3.17.3p1
"...imposes no requirements..." (other than a bit being either one or zero).

Speaking of which, I think it's important to note the relativity of
unspecified values for padding bits. They are unspecified relative to
value and sign bits in an object interpreted as having an integer type
which includes padding bits. I don't think that they are unspecified so
far as to change between reads without intervening stores (which for
'volatile' mightn't be explicit in the program). I think any other
treatment would be chaotic...

Which is why I asked if "last-stored object representation" might be
more accurate for 6.2.4p2. Since "value" implies type[3.17p1], it could
be interpreted as objects having some set type. But as always, I could
be wrong. I would find it quite surprising if copying an 'int' via
'unsigned char[]' followed immediately by an 'unsigned char[]'
comparison of the original and the copy yielded differences because
'int' was somehow secretly the "real type" of the object. Heheh.

Padding bits might be unspecified, but they're not always padding bits. :)

Shao Miller

unread,
Sep 9, 2010, 3:05:51 PM9/9/10
to
Ben Bacarisse wrote:
> lawrenc...@siemens.com writes:
>
>> Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>>> Why can't the padding in the struct change its setting between the copy
>>> and the compare?
>> Because the bytes that compose the struct are themselves objects (that
>> don't have padding bits) and thus subject to the "objects retain their
>> last stored value" guarantee.
>
> That surprises me (but only a little) because of 6.2.6.1 p6. These are
> component objects that retain their last stored value but which may
> change value when other (possibly distant) parts of the larger object
> have *their* stored value changed.
>

The way I try to make sense of it is that C only has one "real" type for
objects: 'unsigned char' (an unsung character type). For
non-addressable storage (like 'register'), perhaps this doesn't apply
quite as much. I pretend that any other type is "projected". So
"last-stored value" to me implies some "real" type, which then to me
means "as unsigned char".

The wording of 6.2.6.1p6 could possibly mean two things:

"When a value with structure or union type is stored into an object with
that type..."

or it could mean:

"When a value with any type is stored into a member of an object with
structure or union type..."

I prefer the former interpretation, as it gives me an "all-at-once"
notion for a contiguous range of storage; some of it being unspecified
and some of it not. Thus the components are being "stored-to" and the
previously stored value is lost.

> BTW, I now think my original claim is wrong but I am still a little
> puzzled by what constitutes the "last stored value" for a padding byte
> in a struct.
>

It was a question until you typed it was a claim. ;)

Ben Bacarisse

unread,
Sep 9, 2010, 7:38:34 PM9/9/10
to
Shao Miller <sha0....@gmail.com> writes:

You posted an example of a scheme for using padding bits. I said this
and dozens of other schemes are permitted. Where is the connection to
the three value formats in signed representations?

I am glad you think it's simple. I still have no idea what you now
agree with and/or don't agree with. If, in some other discussion, I say
that we disagree please bear in mind it may simply be that I have lost
track.

<snip>
--
Ben.

Ben Bacarisse

unread,
Sep 9, 2010, 8:03:11 PM9/9/10
to
Shao Miller <sha0....@gmail.com> writes:

> Ben Bacarisse wrote:
>> lawrenc...@siemens.com writes:
>>
>>> Ben Bacarisse <ben.u...@bsb.me.uk> wrote:
>>>> Why can't the padding in the struct change its setting between the copy
>>>> and the compare?
>>> Because the bytes that compose the struct are themselves objects (that
>>> don't have padding bits) and thus subject to the "objects retain their
>>> last stored value" guarantee.
>>
>> That surprises me (but only a little) because of 6.2.6.1 p6. These are
>> component objects that retain their last stored value but which may
>> change value when other (possibly distant) parts of the larger object
>> have *their* stored value changed.
>>
>
> The way I try to make sense of it is that C only has one "real" type
> for objects: 'unsigned char' (an unsung character type). For
> non-addressable storage (like 'register'), perhaps this doesn't apply
> quite as much. I pretend that any other type is "projected". So
> "last-stored value" to me implies some "real" type, which then to me
> means "as unsigned char".

That's not helping to explain this curiosity to me.

> The wording of 6.2.6.1p6 could possibly mean two things:
>
> "When a value with structure or union type is stored into an object
> with that type..."
>
> or it could mean:
>
> "When a value with any type is stored into a member of an object with
> structure or union type..."
>
> I prefer the former interpretation, as it gives me an "all-at-once"
> notion for a contiguous range of storage; some of it being unspecified
> and some of it not. Thus the components are being "stored-to" and the
> previously stored value is lost.

I don't see how you can choose one interpretation over the other when
the wording of the paragraph seem to me to include both cases. I am not
certain you mean the two cases that 6.2.6.1 p6 covers(because you've
changed the wording slightly) but I think your intent is somehow to
ignore or sideline the "including in a member object" wording.

I read that paragraph as meaning that after:

struct { unsigned char x[3]; } eg; /* assume one padding byte */
memset(&eg, 0, sizeof eg);
eg.x[0] = ' ';

the padding byte may no longer be 0.

This is slightly at odds with Lawrence Jones's statements that the
padding bytes are objects in their own right and thus keep their "last
stored value" like any other. I say "slightly at odds" because is is
possible that what constitutes the "last store" is not a simple and
obvious matter.

[Aside: Despite the esoteric example, I do know why that wording is
there -- it is there to cover the cases where the padding is needed for
efficient reads and stores. Short ints might be padded so as to be able
to load and store in larger chunks. This is very common with bit-fields.
However, the wording means that nothing much can be assumed about the
padding bytes even when there is no practical reason to worry.]

<snip>
--
Ben.

Shao Miller

unread,
Sep 9, 2010, 8:42:08 PM9/9/10
to

My impression is that the Standard has some requirements for padding bits:
1. They are distinct from the "value" and "sign" groups of bits in a
representation of a value with integer type.
2. They are optional.
3. Each one is a unit of data storage having one of two possible values.
4. They may optionally contribute to a trap representation.
5. They may optionally contribute to alternative representations of the
same integer value.
6. They are not padding bits in the context of a representation of a
value with character type.
7. They cannot contribute to a trap representation for a value with
integer type from the result of an arithmetic operation.
8. All other properties are not Standard requirements.

The connection is: Integer type representations are constrained by the
Standard. Value bits are part of integer representations. Value bits
are constrained to one of the three representations. My impression is
that padding bits are constrained as above. Now please take my sentence:

"Then perhaps the authors did not intend to limit the uses of padding
bits and did not intend to constrain integer representations beyond the
three value formats in signed representations."

I was commenting on the possibility that the relevant authors of the
relevant portions of the Standard did not intend to constrain integer
representations to exclude potential uses of padding bits, which is
congruent with your statement:

"Almost everything to [do with] padding bits is unspecified so as to
permit this along with dozens of other schemes."

> ... ... ...


> I am glad you think it's simple. I still have no idea what you now
> agree with and/or don't agree with. If, in some other discussion, I say
> that we disagree please bear in mind it may simply be that I have lost
> track.

Great. I agree that the parity bit example in footnotes 44 and 45 has
relevance to the discussion. They are non-normative, but are intended
to follow from normative text, according to Mr. L. Jones.

There are padding bit usage schemes (only one such described in a
previous post) to meet my suggested padding bit requirement #7 above
while allowing for padding bits to be directly operated upon by
arithmetic operators, and such schemes would then be the only schemes
which padding bits could be used for. So #7 can constrain padding bits,
or #8 can take precedence and #7 follows from other definitions.

Since the Standard constrains value and sign bits, it didn't seem 100%
impossible that the Standard might also attempt to constrain the uses of
padding bits while defining that a bitwise operator such as unary '~'
work directly on all bits; after all, 'unsigned char' works with all
bits, one byte at a time.

I'm happy to simply say "Nope." :) (Except that padding bit uses are
more wild than they might otherwise be, but oh well.)

Ben Bacarisse

unread,
Sep 9, 2010, 9:46:45 PM9/9/10
to
Shao Miller <sha0....@gmail.com> writes:

I think it best to stop this exchange. It appears we can not
communicate with each other effectively.

>> ... ... ...
>> I am glad you think it's simple. I still have no idea what you now
>> agree with and/or don't agree with. If, in some other discussion, I say
>> that we disagree please bear in mind it may simply be that I have lost
>> track.
>
> Great. I agree that the parity bit example in footnotes 44 and 45 has
> relevance to the discussion. They are non-normative, but are intended
> to follow from normative text, according to Mr. L. Jones.
>
> There are padding bit usage schemes (only one such described in a
> previous post) to meet my suggested padding bit requirement #7 above
> while allowing for padding bits to be directly operated upon by
> arithmetic operators, and such schemes would then be the only schemes
> which padding bits could be used for. So #7 can constrain padding
> bits, or #8 can take precedence and #7 follows from other definitions.
>
> Since the Standard constrains value and sign bits, it didn't seem 100%
> impossible that the Standard might also attempt to constrain the uses
> of padding bits while defining that a bitwise operator such as unary
> ~' work directly on all bits; after all, 'unsigned char' works with
> all bits, one byte at a time.
>
> I'm happy to simply say "Nope." :) (Except that padding bit uses are
> more wild than they might otherwise be, but oh well.)

Likewise.

--
Ben.

Shao Miller

unread,
Sep 9, 2010, 9:51:06 PM9/9/10
to
Ben Bacarisse wrote:
> ... ... ...

> This is slightly at odds with Lawrence Jones's statements that the
> padding bytes are objects in their own right and thus keep their "last
> stored value" like any other. I say "slightly at odds" because is is
> possible that what constitutes the "last store" is not a simple and
> obvious matter.
>
> ... ... ...

Ok. Maybe we spread parity throughout the padding of a 'struct', too.
That makes for an excellent new test!

#include <string.h>

int main(void) {
struct three {
unsigned char ca[3];
};
union {
unsigned char ca[sizeof (struct three) + 10];
struct {
union {
struct three alignment;
int dummy;
} dummy;
} dummy;
} foo;
unsigned char *uh_oh;

memset(foo.ca, 'A', sizeof foo.ca);
uh_oh = ((struct three *)&foo)->ca + 2;
*uh_oh = 'B';
/* foo.ca could be AAB???..etc..AAAAAAAAAA */
return 0;
}

Shao Miller

unread,
Sep 9, 2010, 10:20:52 PM9/9/10
to

Or perhaps even better!:

#include <string.h>

int main(void) {
struct three {
unsigned char ca[3];
};
union {

struct {


struct three alignment;
int dummy;

} with_int;
struct {
struct three alignment;
double dummy;
} with_double;
} foo;
unsigned char *uh_oh;

uh_oh = ((struct three *)&foo)->ca + 2;

/*
* Does 'uh_oh' point to:
* foo.with_int.aligment.ca + 2
* Or:
* foo.with_double.alignment.ca + 2
*/
*uh_oh = 'B';
/*
* Which padding bits are unspecified? Those in:
* foo.with_int.alignment ?
* foo.with_int ?
* foo.with_double.alignment ?
* foo.with_double ?
*/
return 0;
}

dS...@arcor.de

unread,
Sep 13, 2010, 8:32:42 AM9/13/10
to
On 7 Sep., 00:51, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> Ian Collins <ian-n...@hotmail.com> writes:
> > ...
> > Find one of those mythical machines with padding bits and have look!
>
> 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.
--
Dietmar

Ben Bacarisse

unread,
Sep 13, 2010, 11:31:48 AM9/13/10
to
"dS...@arcor.de" <dS...@arcor.de> writes:

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

BTW you are quite right about the first part -- I don't think _Bool
*has* to have padding bits either -- but having them is one of the
easiest way to ensure that _Bool behaves as it should so I'd guess it is
not uncommon. That really is a guess though -- it could be that _Bool
has no padding bits more often than it does.

The problem is a subtle one because you can't use the normal means to
determine the maximum value that an unsigned type can hold. For any
unsigned type other than _Bool, T t = -1 initialises t to be the type's
maximum value, but a conversion to _Bool is specifically defined to
produce either 0 or 1.

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

I think you can get close to an answer by defining a bit-field of type
_Bool. The bit-field width can be no larger than the width of the field
type (the width is the number of value bits in an unsigned type). If an
implementation has sizeof (_Bool) == 1 and it permits

struct bt { _Bool b : CHAR_BIT; } s;

then, yes, that implementation has _Bool with no padding. In such cases
I'd want to check that s.b = -1 gave s.b == 1 as specified. gcc 4.4.3
rejects any _Bool bit-field with a size > 1.

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.

--
Ben.

Keith Thompson

unread,
Sep 13, 2010, 2:58:23 PM9/13/10
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:
[...]

> 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:

Certain object representations need not represent a value of
the object type. If the stored value of an object has such a
representation and is read by an lvalue expression that does
not have character type, the behavior is undefined. If such
a representation is produced by a side effect that modifies
all or any part of the object by an lvalue expression that
does not have character type, the behavior is undefined.
Such a representation is called a _trap representation_.

It did affect 6.2.6.1p6, which changed from C99:

When a value is stored in an object of structure or union
type, including in a member object, the bytes of the object
representation that correspond to any padding bytes take
unspecified values. The values of padding bytes shall
not affect whether the value of such an object is a trap
representation. Those bits of a structure or union object that
are in the same byte as a bit-field member, but are not part
of that member, shall similarly not affect whether the value
of such an object is a trap representation.

to N1256:

When a value is stored in an object of structure or union
type, including in a member object, the bytes of the object
representation that correspond to any padding bytes take
unspecified values. The value of a structure or union object is
never a trap representation, even though the value of a member
of the structure or union object may be a trap representation.

There was also a change in the footnote, from:

Thus, for example, structure assignment may be implemented
element-at-a-time or via memcpy.

to:

Thus, for example, structure assignment need not copy any
padding bits.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Ben Bacarisse

unread,
Sep 13, 2010, 3:54:49 PM9/13/10
to
Keith Thompson <ks...@mib.org> writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
> [...]
>> 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>
--
Ben.

Keith Thompson

unread,
Sep 13, 2010, 4:09:11 PM9/13/10
to

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?

Ben Bacarisse

unread,
Sep 13, 2010, 5:14:12 PM9/13/10
to
Keith Thompson <ks...@mib.org> writes:

Ah, very interesting. Thank you. Is there an index that shows what
changes are due to which defect reports? The last time I wanted to know
I downloaded a whole bunch of them and used grep.

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

> 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?

I think it is up to the implementation. I say this simply because I
can't see any reason why either option is prohibited. If the
implementation chooses to give _Bool at least two value bits then it
must print "b = 2" but if there is only one value bit the result is
undefined. Of course, you may well get "b = 2" even when the behaviour
is undefined.

The current definition requires special treatment of _Bool in several
places whereas defining _Bool to have only one value bit would have
almost exactly the same effect with slightly fewer special cases.
Therefore I'd say that the permission to have more than 1 value bit is
deliberate.

--
Ben.

Keith Thompson

unread,
Sep 13, 2010, 6:03:10 PM9/13/10
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:
> Keith Thompson <ks...@mib.org> writes:
[...]

>> 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".
>
> Ah, very interesting. Thank you. Is there an index that shows what
> changes are due to which defect reports? The last time I wanted to know
> I downloaded a whole bunch of them and used grep.

Not that I know of. You mentioned that the change was made in TC2. I
went to <http://www.open-std.org/jtc1/sc22/wg14/www/docs/summary.htm>
and searched for "TC 2" until I found something whose description looked
reasonable.

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

>> 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?
>
> I think it is up to the implementation. I say this simply because I
> can't see any reason why either option is prohibited. If the
> implementation chooses to give _Bool at least two value bits then it
> must print "b = 2" but if there is only one value bit the result is
> undefined. Of course, you may well get "b = 2" even when the behaviour
> is undefined.

And for most implementations, the choice of how many value bits _Bool
has is purely one of documentation.

> The current definition requires special treatment of _Bool in several
> places whereas defining _Bool to have only one value bit would have
> almost exactly the same effect with slightly fewer special cases.
> Therefore I'd say that the permission to have more than 1 value bit is
> deliberate.

I suppose permitting _Bool to have CHAR_BIT*sizeof(_Bool) value
bits means that an implementation may ignore the issue of padding
bits altogether.

_Bool is also the only predefined integer type that doesn't have _MIN
and _MAX macros in <limits.h> or <stdint.h>. It's an oddity.

Ben Bacarisse

unread,
Sep 13, 2010, 11:30:09 PM9/13/10
to
Keith Thompson <ks...@mib.org> writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>> Keith Thompson <ks...@mib.org> writes:
> [...]

<snip>


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

I think you are right, and I'd come to the same conclusion while writing
another post but forgot it by the time I replied here! I see no reason
why _Bool can't be wider that unsigned char.

<snip>
--
Ben.

lawrenc...@siemens.com

unread,
Sep 13, 2010, 10:38:59 PM9/13/10
to
Keith Thompson <ks...@mib.org> wrote:
>
> 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?

I think it's unspecified. It's certainly not required to print "b = 2"
since the width of _Bool is permitted to be 1. It could result in
undefined behavior if the value 2 happens to be a trap representation,
but I don't think there's any undefined behavior otherwise.
--
Larry Jones

Good gravy, whose side are you on?! -- Calvin

lawrenc...@siemens.com

unread,
Sep 13, 2010, 10:40:26 PM9/13/10
to
Keith Thompson <ks...@mib.org> wrote:
>
> _Bool is also the only predefined integer type that doesn't have _MIN
> and _MAX macros in <limits.h> or <stdint.h>.

Since they are, by definition, 0 and 1, there didn't seem to be much
point.
--
Larry Jones

I don't see why some people even HAVE cars. -- Calvin

Seebs

unread,
Sep 14, 2010, 12:35:51 AM9/14/10
to
On 2010-09-14, lawrenc...@siemens.com <lawrenc...@siemens.com> wrote:
> Keith Thompson <ks...@mib.org> wrote:
>> _Bool is also the only predefined integer type that doesn't have _MIN
>> and _MAX macros in <limits.h> or <stdint.h>.

> Since they are, by definition, 0 and 1, there didn't seem to be much
> point.

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.

I think the simplest solution, though, is to just declare that any
value other than 0 or 1 is actually a trap representation, it's just that
the undefined behavior you get from it may include "inexplicably
evaluating to a value outside the range of the type, such as 2, but
not raising any exceptions".

-s
--
Copyright 2010, all wrongs reversed. Peter Seebach / usenet...@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
I am not speaking for my employer, although they do rent some of my opinions.

Peter Nilsson

unread,
Sep 14, 2010, 1:21:49 AM9/14/10
to
Seebs <usenet-nos...@seebs.net> wrote:

> lawrence.jo...@siemens.com <lawrence.jo...@siemens.com> wrote:
> > Keith Thompson <ks...@mib.org> wrote:
> > > _Bool is also the only predefined integer type that doesn't
> > > have _MIN and _MAX macros in <limits.h> or <stdint.h>.
> >
> > Since they are, by definition, 0 and 1, there didn't seem to
> > be much point.
>
> Are they, though?

What other values can you assign to it?

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

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?

--
Peter

Seebs

unread,
Sep 14, 2010, 2:34:13 AM9/14/10
to
On 2010-09-14, Peter Nilsson <ai...@acay.com.au> wrote:
> What other values can you assign to it?

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.

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

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.

Shao Miller

unread,
Sep 14, 2010, 3:21:00 AM9/14/10
to
Seebs wrote:
> On 2010-09-14, Peter Nilsson <ai...@acay.com.au> wrote:
>> What other values can you assign to it?
>
> 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.

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.

> ... ... ...

Shao Miller

unread,
Sep 14, 2010, 3:42:22 AM9/14/10
to

Then again, 6.3.1.2 does say "Boolean". :)

Nick Keighley

unread,
Sep 14, 2010, 4:17:28 AM9/14/10
to
On 6 Sep, 22:39, H Vlems <hvl...@freenet.de> wrote:
> On Sep 6, 11:24 pm, Shao Miller <sha0.mil...@gmail.com> wrote:
>
> > Hello folks.  I hope you're having a nice day today.

its overcast and looks like rain

> > Which of the following groups of bits in an integer type will be
> > complemented by the unary '~' bitwise operator?:
>
> > - value bits
> > - padding bits
> > - the sign bit (for signed integer types)
>
> Why don't you write a little program and let the computer figure it
> out?

because that only tells you what a particular machine (and its
implementaion does), not what the C standard says.

Peter Nilsson

unread,
Sep 16, 2010, 12:46:58 AM9/16/10
to
Seebs <usenet-nos...@seebs.net> wrote:
> Peter Nilsson <ai...@acay.com.au> wrote:
> > 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.

It's not obvious that a value outside the range of unsigned
int can't be stored in an unsigned int with padding bits.

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

We can know for sure whether a given type has padding bits.
We know it has to have a multiple of CHAR_BIT bits of
physical storage.

> > > 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.
> >
> > 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?
>
> None, because UINT_MAX is defined in terms of the values
> that are represented in the type

And _Bool isn't?

> -- but _Bool, never really says that you can't represent
> other values, just that anything assigned into it turns
> into a zero or one.

With the exception of unsigned char, no padded unsigned
integer type ever really says that you can't represent
other values, just that anything assigned (or converted)
into it will fit into its range.

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.

--
Peter

Seebs

unread,
Sep 16, 2010, 12:58:16 AM9/16/10
to
On 2010-09-16, Peter Nilsson <ai...@acay.com.au> wrote:
> Seebs <usenet-nos...@seebs.net> wrote:
>> Peter Nilsson <ai...@acay.com.au> wrote:
>> > 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.

> It's not obvious that a value outside the range of unsigned
> int can't be stored in an unsigned int with padding bits.

Hmm. Interesting point. By definition, padding bits don't contribute
to the value.

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

In which case, I'm pretty sure that the value has to end up being always
exactly zero or one, regardless of the contents of the padding bits.

At least, that would seem to be the intent. In practice, _Bool is a
special case because on most targets it's probably the only integer type
with any padding.

dS...@arcor.de

unread,
Oct 4, 2010, 9:27:14 AM10/4/10
to
On 13 Sep., 17:31, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:

> "dS...@arcor.de" <dS...@arcor.de> writes:
> > The type _Bool needn't necessarily have padding bits. In fact, in
> > every implementation I inspected it hasn't.
>
> 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).

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

--
Dietmar

Ben Bacarisse

unread,
Oct 4, 2010, 12:13:05 PM10/4/10
to
"dS...@arcor.de" <dS...@arcor.de> writes:

> On 13 Sep., 17:31, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
>> "dS...@arcor.de" <dS...@arcor.de> writes:
>> > The type _Bool needn't necessarily have padding bits. In fact, in
>> > every implementation I inspected it hasn't.
>>
>> 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).
>
> 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.

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.

> (By the way, I don't see how one can confuse bits with behaviour.)

It was shorthand for "it is easy to confuse the behaviour you'd expect
from extra value bits with the undefined behaviour that is permitted for
various settings of padding bits".

--
Ben.

dS...@arcor.de

unread,
Oct 5, 2010, 7:31:07 AM10/5/10
to
On 4 Okt., 18:13, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> "dS...@arcor.de" <dS...@arcor.de> writes:
> > On 13 Sep., 17:31, Ben Bacarisse <ben.use...@bsb.me.uk> wrote:
> >> "dS...@arcor.de" <dS...@arcor.de> writes:
> >> > The type _Bool needn't necessarily have padding bits. In fact, in
> >> > every implementation I inspected it hasn't.
>
> >> 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).
>
> > 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.
>
> 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.

I appreciate the possibility of your explanation, that the inspected
translation could be a utilization of the undefinedness of trap
representation access behaviour. Let's note that padding bits are not
necessary for the existence of trap representations; combinations of
value bits which do not represent a value of the object type would
also do.
Now I even get to think that it is by all means (except from an
implementation's documentation) undecidable whether _Bool has padding
bits.

> > (By the way, I don't see how one can confuse bits with behaviour.)
>
> It was shorthand for "it is easy to confuse the behaviour you'd expect
> from extra value bits with the undefined behaviour that is permitted for
> various settings of padding bits".

--
Dietmar

Tim Rentsch

unread,
Oct 20, 2010, 11:40:38 PM10/20/10
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

6.2.5p8. _Bool is an unsigned type, so its width can't
be larger than the width of unsigned char. (The range of
values determines the width, per 6.2.6.2p1 and 6.2.6.2p6.)

Ben Bacarisse

unread,
Oct 21, 2010, 6:42:37 AM10/21/10
to
Tim Rentsch <t...@alumni.caltech.edu> writes:

Ah, so it is. In the context of the thread, if one encounters a system
with sizeof(_Bool) > 1 then one knows it has padding bits.

--
Ben.

0 new messages