473,398 Members | 2,088 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

Bit-fields and integral promotion

Suppose I'm using an implementation where an int is 16 bits.
In the program below, what function is called in the first case,
and what is called in the second case?
Also, if there is a difference between C89 and C99, I would
like to know.
I have tried with different compilers, and I see some differences.
Before I file a bug report with my C vendor, I would like to
know what the correct behavior is.

struct S
{
unsigned int a:4;
unsigned int b:16;
};

void foo(void);
void bar(void);

int main(void)
{
struct S s;
s.a = 0;
s.b = 0;

if (s.a - 5 < 0)
foo();
else
bar();

if (s.b - 5 < 0)
foo();
else
bar();

return 0;
}
Carsten Hansen
Nov 14 '05
112 4246
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
.... snip ...
The point is "what type do we have after extracting the field into
a register". I claim that we have either a signed or unsigned
integer, depending solely on the type designation of the bit field,
and not on its size.


Does that mean you think the standard says promotion of bit-fields is
"unsigned preserving"? That appears to be a minority view.


What's this jargon about unsigned preserving, value preserving,
etc. We extract the bits. If it is an unsigned field we are done
(other bits being zeroed). If it is a signed field we use the left
most field bit to set the final sign, doing the appropriate things
to the other bits formerly unspecified bits. Now we have either a
signed or an unsigned int. Which depends only on the declaration.
No guessing involved. KISS.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #51
"CBFalconer" <cb********@yahoo.com> wrote in message
news:41**************@yahoo.com...
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message

... snip ...
The point is "what type do we have after extracting the field into
a register". I claim that we have either a signed or unsigned
integer, depending solely on the type designation of the bit field,
and not on its size.


Does that mean you think the standard says promotion of bit-fields is
"unsigned preserving"? That appears to be a minority view.


What's this jargon about unsigned preserving, value preserving,
etc.


What's this problem you have with answering my questions? :)

Unsigned preserving: a "small" signed type is promoted to int, and a "small"
unsigned type is promoted to unsigned int.

Values preserving: if int can represent all values of a given "small" type,
it is promoted to int; otherwise it is promoted to unsigned int.

("Small" here covers un/signed bit-fields, un/signed char and un/signed
short.)

Alex
Nov 14 '05 #52
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message

... snip ...

The point is "what type do we have after extracting the field into
a register". I claim that we have either a signed or unsigned
integer, depending solely on the type designation of the bit field,
and not on its size.

Does that mean you think the standard says promotion of bit-fields is
"unsigned preserving"? That appears to be a minority view.


What's this jargon about unsigned preserving, value preserving,
etc.


What's this problem you have with answering my questions? :)

Unsigned preserving: a "small" signed type is promoted to int,
and a "small" unsigned type is promoted to unsigned int.

Values preserving: if int can represent all values of a given
"small" type, it is promoted to int; otherwise it is promoted to
unsigned int.

("Small" here covers un/signed bit-fields, un/signed char and
un/signed short.)


No, small means bit-fields. chars are covered in the standard. In
your terms I claim only unsigned-preserving makes sense.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #53
CBFalconer <cb********@yahoo.com> wrote:
Alex Fraser wrote:
Does that mean you think the standard says promotion of bit-fields is
"unsigned preserving"? That appears to be a minority view.

It's a non-Standard view.
What's this jargon about unsigned preserving, value preserving,
etc.


It's the same jargon that the ISO C Standard Committee uses in their
Rationale:

# The unsigned preserving approach calls for promoting the two smaller
# unsigned types to unsigned int.

# The value preserving approach calls for promoting those types to
# signed int if that type can properly represent all the values of the
# original type, and otherwise for promoting those types to unsigned
# int.

# After much discussion, the C89 Committee decided in favor of
# value preserving rules,

Oh, and

# The Standard clarifies that the integer promotion rules also apply to
# bit fields.

Richard
Nov 14 '05 #54
"Antoine Leca" <ro**@localhost.invalid> writes:
En ln************@nuthaus.mib.org, Keith Thompson va escriure:
"Antoine Leca" <ro**@localhost.invalid> writes:
[...]
I know EOF should be negative. But I cannot find the words that
require it to be different from any unsigned char for a
_freestanding_ implemantation (which may misses the <ctype.h>
header.)
EOF is defined in <stdio.h>, which freestanding implementations
aren't required to provide.


Yes. But I do not see what conclusion you draw from this.

The example code (said to be strictly conforming) assumed that int was
strictly wider than unsigned char. While at the same time it #included
<stdio.h>. My idea is that the fact it #includes <stdio.h> does not force to
use a hosted implementation (that is, a freestanding one can provide a
<stdio.h> header, and a otherwise conforming program could perfectly use
it.)


Hmm. A conforming freestanding implementation doesn't have to provide
<stdio.h>, and doesn't have to accept a strictly conforming program
that uses <stdio.h>. If a freestanding implementation does provide
<stdio.h>, I don't see any requirement for it to do so in a manner
that would be conforming for a hosted implementation; for example,
<stdio.h> might not even define EOF, or it might define EOF as a
positive value.

Certainly a freestanding implementation that provides some of the
non-required headers *should* do so in a consistent manner, but as far
as I can tell the standard doesn't say so.
And on the other hand I cannot spot in the Standard a requirement for a
freestanding implementation to have int strictly wider from [unsigned] char.


I don't see any such (explicit) requirement even for hosted
implementations.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #55
On Tue, 01 Feb 2005 13:20:49 +0000, Kevin Bracey wrote:
In message <11**********************@f14g2000cwb.googlegroups .com>
"Mark Piffer" <so************@yahoo.com> wrote:


....
With your argumentation, the type which is used to define the bitfield
is ignored and the smallest value preserving integer is promoted to;
this would lead to e.g. signed, unsigned, signed for 15,16,17-width
bitfields, would it not?


17-bit bitfields are not permitted on 16-bit systems, so the only issue is
that 16-bit ones promote differently to smaller ones. Just like unsigned
short promoting differently to unsigned char.


The standard says in 6.7.21p4

"A bit-field shall have a type that is a qualified or unqualified version of _Bool, signed
int, unsigned int, or some other implementation-defined type."

So if an implementation supports, say, long and unsigned long bit-fields
as implementation-defined types what constraints on the implementation of
those does the standard specify?

Lawrence

Nov 14 '05 #56
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having the
specified type for any further operations.


It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>

-Larry Jones

You don't get to be Mom if you can't fix everything just right. -- Calvin
Nov 14 '05 #57
Keith Thompson wrote:
"Antoine Leca" <ro**@localhost.invalid> writes:
[...]
I know EOF should be negative. But I cannot find the words that
require it to be different from any unsigned char for a
_freestanding_ implemantation (which may misses the <ctype.h>
header.)


EOF is defined in <stdio.h>, which freestanding implementations
aren't required to provide.


Also in stddef.h and several other places.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #58
CBFalconer <cb********@yahoo.com> writes:
Keith Thompson wrote:
"Antoine Leca" <ro**@localhost.invalid> writes:
[...]
I know EOF should be negative. But I cannot find the words that
require it to be different from any unsigned char for a
_freestanding_ implemantation (which may misses the <ctype.h>
header.)


EOF is defined in <stdio.h>, which freestanding implementations
aren't required to provide.


Also in stddef.h and several other places.


No, <stddef.h> doesn't define EOF. (NULL is defined in several
headers; is that what you were thinking of?)

It's interesting to note that the standard's section on <ctype.h>
refers to the EOF macro, but the macro isn't defined in <ctype.h>.
All it says, though, is that the functions have to accept arguments
with the same value as EOF. An implementer of <ctype.h> has to know
the value of EOF (or has to implement the functions so they accept any
negative argument), but the interface doesn't need it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #59
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having the
specified type for any further operations.


It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>


As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake. There have been
several instances posted in this thread (at least on c.l.c) where
that action leaves the poor programmer in a quandary as to what the
code will do on another machine. One example is the 16 bit
unsigned field, which will be interpreted differently on a 32 bit
and on a 16 bit int machine.

I came to this conclusion from first principles by considering the
rational code generation actions, all elaborated elsewhere in this
thread. This also provides the known treatment from the point of
the language user.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #60
"CBFalconer" <cb********@yahoo.com> wrote in message
news:42**************@yahoo.com...
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having the
specified type for any further operations.
It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>


As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.


The standard very clearly intends to specify the behaviour. Unfortunately,
not in a completely unambiguous manner - hence the defect report.

The wording of the standard is easily understood for types subject to
integer promotion other than bit-fields, and defines different behaviour to
what you suggest should apply to bit-fields. I believe the intention was for
the two to be consistent - bit-fields should be viewed as a "small" type
like unsigned char and unsigned short - and this agrees with the response to
the defect report.
There have been several instances posted in this thread (at least on
c.l.c) where that action leaves the poor programmer in a quandary as to
what the code will do on another machine. One example is the 16 bit
unsigned field, which will be interpreted differently on a 32 bit
and on a 16 bit int machine.
Just like a 16-bit unsigned short.
I came to this conclusion from first principles by considering the
rational code generation actions, all elaborated elsewhere in this
thread.


The only difference between what you suggest and what most people seem to
think the standard says is that for some unsigned bit-fields (those with max
value <= INT_MAX), the latter says promote to signed int whereas you say
promote to unsigned int.

However, code generated for promotion of an unsigned bit-field to signed int
is identical to that for promotion of an unsigned bit-field to unsigned int,
provided the representations of all positive signed int values are identical
to the same unsigned int value. This is normally, if not always, the case.

Therefore I fail to see how considering code generation, rational or
otherwise, could lead you to a conclusion either way on this issue.

Alex
Nov 14 '05 #61
Keith Thompson wrote:
CBFalconer <cb********@yahoo.com> writes:
Keith Thompson wrote:
"Antoine Leca" <ro**@localhost.invalid> writes:
[...]
I know EOF should be negative. But I cannot find the words that
require it to be different from any unsigned char for a
_freestanding_ implemantation (which may misses the <ctype.h>
header.)

EOF is defined in <stdio.h>, which freestanding implementations
aren't required to provide.


Also in stddef.h and several other places.


No, <stddef.h> doesn't define EOF. (NULL is defined in several
headers; is that what you were thinking of?)


I goofed again. Maybe it's just as well Dan Pop is missing.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #62
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having
the specified type for any further operations.

It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>
As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.


The standard very clearly intends to specify the behaviour.
Unfortunately, not in a completely unambiguous manner - hence
the defect report.


Of course it should enforce a behavior. However that behavior
should be both rational and agree with existing practice. It seems
that existing practice already varies.

The wording of the standard is easily understood for types subject
to integer promotion other than bit-fields, and defines different
behaviour to what you suggest should apply to bit-fields. I believe
the intention was for the two to be consistent - bit-fields should
be viewed as a "small" type like unsigned char and unsigned short -
and this agrees with the response to the defect report.
Others, and I, have pointed out the anomalies that can result from
this attitude. The opportunity should be taken to clean this up
without contravening any earlier standard. C is already a morass
of insecurities, there is no need to add another.

One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0. This is contrary to the usual C practice. The
opportunity exists to ensure that booleans stored in bit fields are
properly expanded. Or should we have to write !!x for any boolean
x stored in a bitfield?
There have been several instances posted in this thread (at least
on c.l.c) where that action leaves the poor programmer in a
quandary as to what the code will do on another machine. One
example is the 16 bit unsigned field, which will be interpreted
differently on a 32 bit and on a 16 bit int machine.
Just like a 16-bit unsigned short.
I came to this conclusion from first principles by considering
the rational code generation actions, all elaborated elsewhere
in this thread.


The only difference between what you suggest and what most people
seem to think the standard says is that for some unsigned
bit-fields (those with max value <= INT_MAX), the latter says
promote to signed int whereas you say promote to unsigned int.

However, code generated for promotion of an unsigned bit-field
to signed int is identical to that for promotion of an unsigned
bit-field to unsigned int, provided the representations of all
positive signed int values are identical to the same unsigned
int value. This is normally, if not always, the case.


No, it is not. It is dependant on the value of the sign bit of the
restricted bit field, if you insist on the so called 'value
preserving' interpretation here rather than 'signed preserving'.

Therefore I fail to see how considering code generation, rational
or otherwise, could lead you to a conclusion either way on this
issue.


Simple - signed preservation leads to consistent interpretation by
the user, minimization of generated code, and reduction of code in
the code generator. Due to the ambiguity of the present standard
the opportunity exists to specify this correctly. Do so.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #63

Kevin Bracey wrote:
In message <11**********************@f14g2000cwb.googlegroups .com>
"Mark Piffer" <so************@yahoo.com> wrote:
Jack Klein wrote:
Admittedly it is unfortunate that the standard does not specifically mention bit fields in describing the usual integer conversions, and hopefully that can be rectified in a TC or later version.

But since the standard selected what they call "value preserving" over "sign preserving" operation, it would be seriously inconsistent and a real source of problems if an 8-bit unsigned char promoted to a signed int but an 8-bit unsigned bit field promoted to an unsigned int. That would be rather absurd, don't you think?
One could claim that it is equally absurd to have a unsigned bit field of width 15 promoted to int and one of width 16 to unsigned int
(following value-preservation rules on an example 16-Bit architecture).
No more absurd than

unsigned char uc;
unsigned short us;

uc + 1 -> int
us + 1 -> unsigned int

is it? Unsigned short promotes to unsigned int only because it is 16 bits like int. Unsigned char does not. On another, 32-bit, implementation unsigned short would promote to int. This "absurdity" already exists for the main types. True, but what I was pointing out is that you have another
implementation dependent partial order of conversion ranks that you
need to fit (mentally) into the existing one, when with the sign
preservation rule you could have got away very cheap.
With your argumentation, the type which is used to define the
bitfield is ignored and the smallest value preserving integer is promoted to; this would lead to e.g. signed, unsigned, signed for 15,16,17-width
bitfields, would it not?


17-bit bitfields are not permitted on 16-bit systems, so the only

issue is that 16-bit ones promote differently to smaller ones. Just like unsigned short promoting differently to unsigned char.

To me 6.7.2.1p4 reads as if the width is an implementation defined
thing, just the use of a bitfield exceeding the width of an int in a
conversion or promotion is left unspecified (I found nothing conclusive
in 6.3). It seems reasonable that at least an assignment is allowed.
OTOH, this makes my previous answer pointless, as any use of an
unsigned bitfield in most expressions is either unproblematic (positive
int -> unsigned int) or not defined at all. (shrug)

Mark

Nov 14 '05 #64
CBFalconer <cb********@yahoo.com> wrote:

One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0. This is contrary to the usual C practice. The
opportunity exists to ensure that booleans stored in bit fields are
properly expanded. Or should we have to write !!x for any boolean
x stored in a bitfield?
Use an unsigned bit field of course.
Simple - signed preservation leads to consistent interpretation by
the user, minimization of generated code, and reduction of code in
the code generator. Due to the ambiguity of the present standard
the opportunity exists to specify this correctly. Do so.


That would be to reverse a decision made over 15 years ago. If you
want K&R C you know where to find it...

Tony.
--
f.a.n.finch <do*@dotat.at> http://dotat.at/
NORTH FORELAND TO SELSEY BILL: NORTH OR NORTHWEST 4 OR 5, OCCASIONALLY 6 IN
THE EAST. MOSTLY FAIR. MAINLY GOOD. SLIGHT.
Nov 14 '05 #65
"CBFalconer" <cb********@yahoo.com> wrote in message
news:42***************@yahoo.com...
[snip]
One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0.


No! An unsigned 1 bit bit-field can (obviously) hold the values 0 and 1.
"Value preserving" promotion should result in a signed int with the same
value (otherwise "value preserving" would be a pretty stupid name).

In code generation terms, you only copy/move the sign bit when the
unpromoted type is signed, not when the promoted type is signed. Perhaps
this example exposes the root of your misunderstanding.

Alex
Nov 14 '05 #66
On Wed, 02 Feb 2005 02:10:09 +0000, CBFalconer wrote:
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having the
specified type for any further operations.
It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>


As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.


Unfortunately there is just too much else in the standard that depends on
bit-field width being considered as a part of the type. Consider for
example assigning an out of range value to an unsigned bit-field in the
context of 6.3.1.3p2.
There have been
several instances posted in this thread (at least on c.l.c) where
that action leaves the poor programmer in a quandary as to what the
code will do on another machine. One example is the 16 bit
unsigned field, which will be interpreted differently on a 32 bit
and on a 16 bit int machine.
That's an example of the problem with the overall value-preserving
rules, not just bit-fields. You have no argument from me that
unsigned-preserving rules would have been much better for the language.
But that's not what we have and trying to make bit-fields unsigned
preserving while char and short promotions remain value preserving is
probably not a good idea.
I came to this conclusion from first principles by considering the
rational code generation actions, all elaborated elsewhere in this
thread. This also provides the known treatment from the point of
the language user.


Whether you use value or unsigned preserving rules doesn't make any
difference to code generation for the promotion. In both cases the result
of promoting an unsigned value is a positive value which has the same
representation in a signed or unsigned int type.

Lawrence
Nov 14 '05 #67
On Wed, 02 Feb 2005 13:02:08 +0000, Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
news:42***************@yahoo.com...
[snip]
One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0.


No! An unsigned 1 bit bit-field can (obviously) hold the values 0 and 1.
"Value preserving" promotion should result in a signed int with the same
value (otherwise "value preserving" would be a pretty stupid name).


To be honest it is. Any promotion mechanism that didn't preserve value
would be rather silly. Unsigned preserving promotion also preserves value.
So preserving value is not a distinguishing feature of the standard's
integer promotions.

Lawrence
Nov 14 '05 #68
In message <pa****************************@netactive.co.uk>
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Tue, 01 Feb 2005 13:20:49 +0000, Kevin Bracey wrote:
17-bit bitfields are not permitted on 16-bit systems, so the only issue
is that 16-bit ones promote differently to smaller ones. Just like
unsigned short promoting differently to unsigned char.


The standard says in 6.7.21p4

"A bit-field shall have a type that is a qualified or unqualified version
of _Bool, signed
int, unsigned int, or some other implementation-defined type."

So if an implementation supports, say, long and unsigned long bit-fields
as implementation-defined types what constraints on the implementation of
those does the standard specify?


Such things are not subject to integer promotions, according to 6.3.1.1p2.
It doesn't seem terribly concrete, but I think that may mean that a "long:4"
just functions as a long? What about a "unsigned char:4"? Does it act as a
unsigned char, and hence get promoted?

Ew. Bitfields on larger types are not something I'm familiar with, as our
systems don't support it.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #69
CBFalconer wrote:
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
la************@ugs.com wrote: ....It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>
....The wording of the standard is easily understood for types subject
to integer promotion other than bit-fields, and defines different
behaviour to what you suggest should apply to bit-fields. I believe
the intention was for the two to be consistent - bit-fields should
be viewed as a "small" type like unsigned char and unsigned short -
and this agrees with the response to the defect report.
.... One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0. This is contrary to the usual C practice. The
This "attitude" (correct interpretation of the standard, as confirmed by
the Committee's decision on DR 122), calls for value-preserving
conversion of the 1 bit field to int. Therefore, if it's declared as
unsigned, the result must be either 0 or 1, not -1.
opportunity exists to ensure that booleans stored in bit fields are
properly expanded. Or should we have to write !!x for any boolean
x stored in a bitfield?


"If the value 0 or 1 is stored into a nonzerowidth bit-field of type
_Bool, the value of the bit-field shall compare equal to the value stored."

The value-preserving conversion to int can therefore only produce a 0 or
a 1.
Nov 14 '05 #70
Tony Finch wrote:
CBFalconer <cb********@yahoo.com> wrote:
.... snip ...
Simple - signed preservation leads to consistent interpretation by
the user, minimization of generated code, and reduction of code in
the code generator. Due to the ambiguity of the present standard
the opportunity exists to specify this correctly. Do so.


That would be to reverse a decision made over 15 years ago. If you
want K&R C you know where to find it...


No such decision has been embodied in the standard, so it doesn't
count.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #71
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 02:10:09 +0000, CBFalconer wrote:
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

It would suffice to say that any bitfield is treated as having the
specified type for any further operations.

It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>


As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.


Unfortunately there is just too much else in the standard that
depends on bit-field width being considered as a part of the type.
Consider for example assigning an out of range value to an unsigned
bit-field in the context of 6.3.1.3p2.


For this purpose that is just one more black cat in the dark. The
values are known to be positive, and the standard insists on binary
representation, so masking off a set of less significant bits
produces the same answer for all three flavors. All that has to be
done is make a conversion to some form of unsigned (if needed) in
the original, not in the potential 30 odd or more types pseudo
created by bit fields.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #72
CBFalconer wrote:
Tony Finch wrote:

....
That would be to reverse a decision made over 15 years ago. If you
want K&R C you know where to find it...

No such decision has been embodied in the standard, so it doesn't
count.


The decision merely confirmed a meaning that was already (albeit
unclearly) embodied in the standard.
Nov 14 '05 #73
CBFalconer <cb********@yahoo.com> wrote:
Tony Finch wrote:

That would be to reverse a decision made over 15 years ago. If you
want K&R C you know where to find it...


No such decision has been embodied in the standard, so it doesn't
count.


Er, what? K&R C was signedness-preserving but ANSI C has deliberately
different promotion rules.

Tony.
--
f.a.n.finch <do*@dotat.at> http://dotat.at/
SOUTHEAST ICELAND: SOUTHWEST 7 TO SEVERE GALE 9, BACKING SOUTH 5 TO 7. RAIN OR
SHOWERS. MODERATE OR GOOD.
Nov 14 '05 #74
"Lawrence Kirby" <lk****@netactive.co.uk> wrote in message
news:pa****************************@netactive.co.u k...
On Wed, 02 Feb 2005 13:02:08 +0000, Alex Fraser wrote:
No! An unsigned 1 bit bit-field can (obviously) hold the values 0 and
1. "Value preserving" promotion should result in a signed int with the
same value (otherwise "value preserving" would be a pretty stupid
name).


To be honest it is. Any promotion mechanism that didn't preserve value
would be rather silly. Unsigned preserving promotion also preserves
value. So preserving value is not a distinguishing feature of the
standard's integer promotions.


Granted; "unsigned preserving" is logically a subclass of "value preserving"
but I think it's basically a case of giving a concise name to the behaviour.
There's no immediately obvious and superior alternative that I can think of.

Alex
Nov 14 '05 #75
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 13:02:08 +0000, Alex Fraser wrote:

....
No! An unsigned 1 bit bit-field can (obviously) hold the values 0 and 1.
"Value preserving" promotion should result in a signed int with the same
value (otherwise "value preserving" would be a pretty stupid name).

To be honest it is. Any promotion mechanism that didn't preserve value
would be rather silly. Unsigned preserving promotion also preserves value.
So preserving value is not a distinguishing feature of the standard's
integer promotions.


It's not exactly correct terminology, but there is a connection. Both
kinds of promotions are value preserving in themselves. However, the
"value preserving" rules result in signed types more often than the
"signedness preserving" rules did. As a result, there's less frequent
need for a signed value to be converted to an unsigned type, a
conversion that can't be value preserving the value is negative.
Nov 14 '05 #76
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:

As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.
Of course it's "officially incorporated into the standard", DR 122 is 11
years old and DR 015 that it references is 12 years old! The DRs don't
propose any change to the text of the standard, the implication being
that the committee believes the existing text to be clear enough as is.
There have been
several instances posted in this thread (at least on c.l.c) where
that action leaves the poor programmer in a quandary as to what the
code will do on another machine. One example is the 16 bit
unsigned field, which will be interpreted differently on a 32 bit
and on a 16 bit int machine.


You're just rehashing the argument about unsigned preserving promotion
rules as opposed to value preserving promotion rules. That train left
the station long ago -- the battle was fought and value preserving
promotions won. Bit fields are no different than other "small" types --
having different promotions for them would be sheer lunacy.

-Larry Jones

Any game without push-ups, hits, burns or noogies is a sissy game. -- Calvin
Nov 14 '05 #77
In comp.std.c Tony Finch <do*@dotat.at> wrote:

Er, what? K&R C was signedness-preserving but ANSI C has deliberately
different promotion rules.


Wrong. K&R only had one explicitly unsigned type: unsigned int. As
such, the promotion rules are agnostic. Pre-ANSI compilers that added
additional unsigned types varied between unsigned preserving and value
preserving.

However, it's worth noting that char was implicitly unsigned on some
platforms (notably EBCDIC platforms, due to the requirement that members
of the standard character set have non-negative values). It nonetheless
promoted to int, not unsigned int, the first example of value preserving
behavior.

-Larry Jones

In a minute, you and I are going to settle this out of doors. -- Calvin
Nov 14 '05 #78
Alex Fraser wrote:
"Lawrence Kirby" <lk****@netactive.co.uk> wrote in message
news:pa****************************@netactive.co.u k...
On Wed, 02 Feb 2005 13:02:08 +0000, Alex Fraser wrote:
No! An unsigned 1 bit bit-field can (obviously) hold the values 0 and
1. "Value preserving" promotion should result in a signed int with the
same value (otherwise "value preserving" would be a pretty stupid
name).


To be honest it is. Any promotion mechanism that didn't preserve value
would be rather silly. Unsigned preserving promotion also preserves
value. So preserving value is not a distinguishing feature of the
standard's integer promotions.

Granted; "unsigned preserving" is logically a subclass of "value preserving"
but I think it's basically a case of giving a concise name to the behaviour.
There's no immediately obvious and superior alternative that I can think of.


"prefer-signed"?

--
David Hopwood <da******************@blueyonder.co.uk>
Nov 14 '05 #79
En ln************@nuthaus.mib.org, Keith Thompson va escriure:
"Antoine Leca" <ro**@localhost.invalid> writes:
The example code (said to be strictly conforming) assumed that int
was strictly wider than unsigned char. While at the same time it
#included <stdio.h>. My idea is that the fact it #includes
<stdio.h> does not force to use a hosted implementation (that is,
a freestanding one can provide a <stdio.h> header, and a otherwise
conforming program could perfectly use it.)
Hmm. A conforming freestanding implementation doesn't have to
provide <stdio.h>, and doesn't have to accept a strictly conforming
program that uses <stdio.h>.


Right. But I am looking from the other side. I have a program which is
claimed to be s.c. ("[The output] must be so with any C compiler"); OTOH it
#includes <stdio.h>. I am arguing that an otherwise compliant freestanding
implementation could provide an (unrequired) <stdio.h> header, so will
compile this program, yet have int of the same width as unsigned char so
will result in the program outputting something different.
If a freestanding implementation does provide
<stdio.h>, I don't see any requirement for it to do so in a manner
that would be conforming for a hosted implementation;


Neither do I. Which is why I challenged the claim.

And on the other hand I cannot spot in the Standard a
requirement for a freestanding implementation to have int strictly
wider from [unsigned] char.


I don't see any such (explicit) requirement even for hosted
implementations.


This might be inferred from the requirement for <ctype.h>:
In all cases the argument is an /int/, the value of which
shall be representable as an /unsigned char/ or shall equal
the value of the macro /EOF/.

I shall not try to convince you on this one since I am feeling there is thin
ice here (and I believe this is as intended, in order to not explicitely
break implementations on computers without "narrow" register access); yet my
reading is that to comply with this, unsigned char should promote to signed
int not unsigned int, and it then comes that int should be "wider".
Antoine

Nov 14 '05 #80
On Wed, 02 Feb 2005 14:55:16 +0000, CBFalconer wrote:
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 02:10:09 +0000, CBFalconer wrote:
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:
>
> It would suffice to say that any bitfield is treated as having the
> specified type for any further operations.

It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>

As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.
Unfortunately there is just too much else in the standard that
depends on bit-field width being considered as a part of the type.
Consider for example assigning an out of range value to an unsigned
bit-field in the context of 6.3.1.3p2.


For this purpose that is just one more black cat in the dark.


It is a clear example of where the standard requires the width of a
bit-field to be part of its type. Once you accept that is inevitable all
else follows.
The
values are known to be positive, and the standard insists on binary
representation, so masking off a set of less significant bits
produces the same answer for all three flavors. All that has to be
done is make a conversion to some form of unsigned (if needed) in
the original, not in the potential 30 odd or more types pseudo
created by bit fields.


The question is not what could be done or what would be sensible to do,
but what the standard actually requires. And as you seem to be saying it
makes no difference from a code generation point of view.

Lawrence
Nov 14 '05 #81
On Wed, 02 Feb 2005 11:06:10 -0500, James Kuyper wrote:

....
It's not exactly correct terminology, but there is a connection. Both
kinds of promotions are value preserving in themselves. However, the
"value preserving" rules result in signed types more often than the
"signedness preserving" rules did. As a result, there's less frequent
need for a signed value to be converted to an unsigned type, a
conversion that can't be value preserving the value is negative.


A little indirect, but OK. :-)

Lawrence
Nov 14 '05 #82
On Wed, 02 Feb 2005 21:09:00 +0000, lawrence.jones wrote:
In comp.std.c Tony Finch <do*@dotat.at> wrote:

Er, what? K&R C was signedness-preserving but ANSI C has deliberately
different promotion rules.


Wrong. K&R only had one explicitly unsigned type: unsigned int. As
such, the promotion rules are agnostic. Pre-ANSI compilers that added
additional unsigned types varied between unsigned preserving and value
preserving.

However, it's worth noting that char was implicitly unsigned on some
platforms (notably EBCDIC platforms, due to the requirement that members
of the standard character set have non-negative values). It nonetheless
promoted to int, not unsigned int, the first example of value preserving
behavior.


I suspected that char was the cause of the whole situation. :-) Normally
signed and unsigned integer types are useful for separate problem
domains and mixing them doesn't really make sense. Character handling is
another problem domain again and the desire to promote plain char (which
could be signed or unsigned) to something consistent, with int well
established for character handling, is probably what started C down the
slippery slope.

Lawrence
Nov 14 '05 #83
On Thu, 03 Feb 2005 13:18:50 +0100, Antoine Leca wrote:

....
If a freestanding implementation does provide
<stdio.h>, I don't see any requirement for it to do so in a manner
that would be conforming for a hosted implementation;


Neither do I. Which is why I challenged the claim.


Interesting. According to 4p6 A conforming freestanding implementation
isn't required to accept a program that uses <stdio.h>. However 5.1.2.1p1
says

"... Any library facilities available to a freestanding
program, other than the minimal set required by clause 4, are
implementation-defined."

So yes I agree a freestanding implementatin of <stdio.h> need not bear any
relation to a hosted one.
And on the other hand I cannot spot in the Standard a
requirement for a freestanding implementation to have int strictly
wider from [unsigned] char.


I don't see any such (explicit) requirement even for hosted
implementations.


This might be inferred from the requirement for <ctype.h>:
In all cases the argument is an /int/, the value of which shall be
representable as an /unsigned char/ or shall equal the value of the
macro /EOF/.

I shall not try to convince you on this one since I am feeling there is
thin ice here (and I believe this is as intended, in order to not
explicitely break implementations on computers without "narrow" register
access); yet my reading is that to comply with this, unsigned char
should promote to signed int not unsigned int, and it then comes that
int should be "wider".


I don't see a requirement here that every possible value of unsigned char
be passable to the function. Therefore this does not require that
INT_MAX >= UCHAR_MAX.

Lawrence

Nov 14 '05 #84
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 11:06:10 -0500, James Kuyper wrote:

...
It's not exactly correct terminology, but there is a connection.
Both kinds of promotions are value preserving in themselves.
However, the "value preserving" rules result in signed types more
often than the "signedness preserving" rules did. As a result,
there's less frequent need for a signed value to be converted to
an unsigned type, a conversion that can't be value preserving the
value is negative.


A little indirect, but OK. :-)


Although I don't agree with the philosophy, one attitude could be
that conversion to signed (where possible) averts any future need
to convert unsigned to signed, which is overflow sensitive and thus
not guaranteed possible.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #85
On Wed, 02 Feb 2005 14:23:31 +0000, Kevin Bracey wrote:
In message <pa****************************@netactive.co.uk>
Lawrence Kirby <lk****@netactive.co.uk> wrote:
On Tue, 01 Feb 2005 13:20:49 +0000, Kevin Bracey wrote:
> 17-bit bitfields are not permitted on 16-bit systems, so the only issue
> is that 16-bit ones promote differently to smaller ones. Just like
> unsigned short promoting differently to unsigned char.
The standard says in 6.7.21p4

"A bit-field shall have a type that is a qualified or unqualified version
of _Bool, signed
int, unsigned int, or some other implementation-defined type."

So if an implementation supports, say, long and unsigned long bit-fields
as implementation-defined types what constraints on the implementation of
those does the standard specify?


Such things are not subject to integer promotions, according to 6.3.1.1p2.
It doesn't seem terribly concrete, but I think that may mean that a "long:4"
just functions as a long?


Seems to be, it certainly isn't one of the bit-field types specified in
6.3.1.1p2, and there's nothing in 6.3.1.1.p1 to suggest that it has a
lower rank than int.
What about a "unsigned char:4"? Does it act as a
unsigned char, and hence get promoted?
I guess so, it is unclear though. The alternative i.e. having unpromoted
unsigned char values around after the integer promotions could be
problematic.
Ew. Bitfields on larger types are not something I'm familiar with, as our
systems don't support it.


Nevertheless it is something that the standard explicitly allows an
implementation to support.

Lawrence
Nov 14 '05 #86
On Thu, 03 Feb 2005 15:59:30 +0000, CBFalconer wrote:
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 11:06:10 -0500, James Kuyper wrote:

...
It's not exactly correct terminology, but there is a connection.
Both kinds of promotions are value preserving in themselves.
However, the "value preserving" rules result in signed types more
often than the "signedness preserving" rules did. As a result,
there's less frequent need for a signed value to be converted to
an unsigned type, a conversion that can't be value preserving the
value is negative.


A little indirect, but OK. :-)


Although I don't agree with the philosophy, one attitude could be
that conversion to signed (where possible) averts any future need
to convert unsigned to signed, which is overflow sensitive and thus
not guaranteed possible.


If it was going to overflow it would end up as unsigned int anyway. If it
was going to overflow after subsequent operations you would have signed
integer overflow if you performed the operations as signed integers. If
you perform suitable checking for overflow it doesn't matter which you
use, although unsigned might be easier.

Lawrence

Nov 14 '05 #87
Lawrence Kirby wrote:

On Thu, 03 Feb 2005 15:59:30 +0000, CBFalconer wrote:
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 11:06:10 -0500, James Kuyper wrote:

...

It's not exactly correct terminology, but there is a connection.
Both kinds of promotions are value preserving in themselves.
However, the "value preserving" rules result in signed types more
often than the "signedness preserving" rules did. As a result,
there's less frequent need for a signed value to be converted to
an unsigned type, a conversion that can't be value preserving the
value is negative.

A little indirect, but OK. :-)


Although I don't agree with the philosophy, one attitude could be
that conversion to signed (where possible) averts any future need
to convert unsigned to signed, which is overflow sensitive and thus
not guaranteed possible.


If it was going to overflow it would end up as unsigned int anyway. If it
was going to overflow after subsequent operations you would have signed
integer overflow if you performed the operations as signed integers. If
you perform suitable checking for overflow it doesn't matter which you
use, although unsigned might be easier.


I said future, as in further operations on the variable. I think
we all know we can never safely cast an arbitrary unsigned to the
corresponding signed form.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #88
Lawrence Kirby wrote:
On Wed, 02 Feb 2005 14:23:31 +0000, Kevin Bracey wrote:
.... snip ...
Ew. Bitfields on larger types are not something I'm familiar with,
as our systems don't support it.


Nevertheless it is something that the standard explicitly allows
an implementation to support.


So, instead of valiantly defending the status quo it seems it would
be more productive to concentrate on clearing up this whole area,
in such a way as to produce the fewest surprises and the most
clarity. I claim anything that has not made it into the standard
remains an open question.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson

Nov 14 '05 #89
On Wed, 02 Feb 2005 09:52:40 GMT, CBFalconer <cb********@yahoo.com>
wrote in comp.std.c:
Alex Fraser wrote:
"CBFalconer" <cb********@yahoo.com> wrote in message
la************@ugs.com wrote:
In comp.std.c CBFalconer <cb********@yahoo.com> wrote:
>
> It would suffice to say that any bitfield is treated as having
> the specified type for any further operations.

It would also be completely wrong. See DR 122:

<http://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_122.html>

As you may have gathered from my previous postings, I am deeply
opposed to that. It obviously isn't officially incorporated into
the standard, and doing so would be a mistake.
The standard very clearly intends to specify the behaviour.
Unfortunately, not in a completely unambiguous manner - hence
the defect report.


Of course it should enforce a behavior. However that behavior
should be both rational and agree with existing practice. It seems
that existing practice already varies.

The wording of the standard is easily understood for types subject
to integer promotion other than bit-fields, and defines different
behaviour to what you suggest should apply to bit-fields. I believe
the intention was for the two to be consistent - bit-fields should
be viewed as a "small" type like unsigned char and unsigned short -
and this agrees with the response to the defect report.


Others, and I, have pointed out the anomalies that can result from
this attitude. The opportunity should be taken to clean this up
without contravening any earlier standard. C is already a morass
of insecurities, there is no need to add another.


Personally I would have preferred the choice of "sign preserving"
promotions over the "value preserving" that was selected by the
committee. Apparently there were pre-standard implementations that
promoted unsigned char to signed int, although I can't remember ever
using one in the K&R days.
One ridiculous result of this attitude is that a 1 bit field,
whether declared as int or unsigned int, would always be treated as
-1 or 0. This is contrary to the usual C practice. The
opportunity exists to ensure that booleans stored in bit fields are
properly expanded. Or should we have to write !!x for any boolean
x stored in a bitfield?


The ridiculous thing about the paragraph above is your conclusion, as
I'm sure you'd realize if you rethink it carefully.

A signed int 1 bit field can indeed only contain the values 0 and -1.

An unsigned int 1 bit field can only contain the values 0 and 1. If
it contains the value 1, it will promote to a signed int with the
value 1. How can you possible maintain that it promotes to -1 in a
signed int? Perhaps you are thinking of how you would write assembly
language for some particular processor, but that has nothing to do
with preserving the value.

C conversions, and integral promotions, are always about the value,
not about the bit pattern.

Given the fact that "value preserving" has been the language standard
for a decade and a half, it is far more important that unsigned bit
fields promote exactly the same way is lesser rank integer types of
the same with and range of values.

Assume one of today's most common desk top platform with 8-bit chars,
16-bit shorts, and 32-bit ints. Now consider:

#include <stdio.h>

struct nu
{
unsigned uc: 8;
unsigned us: 16;
};

int main(void)
{
unsigned char uc = 0;
unsigned short us = 0;
struct nu nu = { 0, 0 };
if ((uc - 5) < 0)
puts("unsigned char promotes to signed");
else
puts("unsigned char promotes to unsigned");
if ((nu.uc - 5) < 0)
puts("unsigned :8 promotes to signed");
else
puts("unsigned :8 promotes to unsigned");
if ((us - 5) < 0)
puts("unsigned short promotes to signed");
else
puts("unsigned short promotes to unsigned");
if ((nu.us - 5) < 0)
puts("unsigned :16 promotes to signed");
else
puts("unsigned :16 promotes to unsigned");
return 0;
}

Under your interpretation, the results are different for the 8-bit
unsigned bit-field and the 8-bit unsigned char, and also different for
the 16-bit unsigned bit-field and the 16-bit unsigned short.

Amazingly, I just tested this with four compilers, all of which got it
wrong.

But the standard does specifically say you are wrong:

6.7.2.1 Structure and union specifiers P9:

"A bit-field is interpreted as a signed or unsigned integer type
consisting of the specified number of bits."

So the type of an unsigned int bit field is NOT unsigned int, it is a
(perhaps unnamed type) uintn_t, where 'n' is the width in bits.

And:

6.3.1.1 Boolean, characters, and integers P1

"The rank of a signed integer type shall be greater than the rank of
any signed integer type with less precision."
[snip]
"The rank of any unsigned integer type shall equal the rank of the
corresponding signed integer type, if any."

And finally:

6.3.1.2 P2

"If an int can represent all values of the original type, the value is
converted to an int; otherwise, it is converted to an unsigned int."

The first quote makes it clear that the type of an 'n' bit unsigned
integer bit-field is "n-bit unsigned integer type". By the definition
of all unsigned integer types, it has a precision of n-bits.

If n is less than the number of value bits in a signed int, it is
quite clear that this "n-bit unsigned integer type" has a lesser rank
than type int. This means it is subjected to the "integer
promotions".

And since an int can hold all the values of this type, it must be
promoted to int, not unsigned int.

While these quotations are copied and pasted from a copy of C99, C90
contained the same.

"The opportunity should be taken to clean this up without contravening
any earlier standard." is not possible.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #90
Jack Klein wrote:
.... snip ...
Given the fact that "value preserving" has been the language standard
for a decade and a half, it is far more important that unsigned bit
fields promote exactly the same way is lesser rank integer types of
the same with and range of values.


For types other than bit-fields. However the bit-field language is
ambiguous, and all I am saying is that the opportunity exists to
clean it up to a sensible meaning, and that that sensible meaning
should be unsigned preserving.

Remember, joe q programmer has written "unsigned int" for the type
of the bit field. If he uses the content of that field, he should
expect to get an unsigned int that obeys the laws for unsigned
ints. If he uses that content in some other type, then the value
preserving language of the standard kicks in.

Doing things that way even requires less effort than the misguided
conversion to signed int.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #91
Jack Klein <ja*******@spamcop.net> writes:
Assume one of today's most common desk top platform with 8-bit chars,
16-bit shorts, and 32-bit ints. Now consider:

#include <stdio.h>

struct nu
{
unsigned uc: 8;
unsigned us: 16;
};

int main(void)
{
unsigned char uc = 0;
unsigned short us = 0;
struct nu nu = { 0, 0 };
if ((uc - 5) < 0)
puts("unsigned char promotes to signed");
else
puts("unsigned char promotes to unsigned");
if ((nu.uc - 5) < 0)
puts("unsigned :8 promotes to signed");
else
puts("unsigned :8 promotes to unsigned");
if ((us - 5) < 0)
puts("unsigned short promotes to signed");
else
puts("unsigned short promotes to unsigned");
if ((nu.us - 5) < 0)
puts("unsigned :16 promotes to signed");
else
puts("unsigned :16 promotes to unsigned");
return 0;
}

Under your interpretation, the results are different for the 8-bit
unsigned bit-field and the 8-bit unsigned char, and also different for
the 16-bit unsigned bit-field and the 16-bit unsigned short.

Amazingly, I just tested this with four compilers, all of which got it
wrong.


Which ones, and what were the results?
Nov 14 '05 #92
Jack Klein <ja*******@spamcop.net> writes:
[...]
Assume one of today's most common desk top platform with 8-bit chars,
16-bit shorts, and 32-bit ints. Now consider:

#include <stdio.h>

struct nu
{
unsigned uc: 8;
unsigned us: 16;
};

int main(void)
{
unsigned char uc = 0;
unsigned short us = 0;
struct nu nu = { 0, 0 };
if ((uc - 5) < 0)
puts("unsigned char promotes to signed");
else
puts("unsigned char promotes to unsigned");
if ((nu.uc - 5) < 0)
puts("unsigned :8 promotes to signed");
else
puts("unsigned :8 promotes to unsigned");
if ((us - 5) < 0)
puts("unsigned short promotes to signed");
else
puts("unsigned short promotes to unsigned");
if ((nu.us - 5) < 0)
puts("unsigned :16 promotes to signed");
else
puts("unsigned :16 promotes to unsigned");
return 0;
}

Under your interpretation, the results are different for the 8-bit
unsigned bit-field and the 8-bit unsigned char, and also different for
the 16-bit unsigned bit-field and the 16-bit unsigned short.

Amazingly, I just tested this with four compilers, all of which got it
wrong.


Interesting. I just tried it with a number of compilers, and they all
got it right (everything promotes to signed).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 14 '05 #93
Hi,
I am wondering that in GCC bith cases are "Foo". If I remove bit
fileds in structure and executes, it gives "Bar". Can any one helps me
in explaning why unsigned type is not considering in presence of bit
fileds?.

Thanks,
YTR

Carsten Hansen wrote:
Suppose I'm using an implementation where an int is 16 bits.
In the program below, what function is called in the first case,
and what is called in the second case?
Also, if there is a difference between C89 and C99, I would
like to know.
I have tried with different compilers, and I see some differences.
Before I file a bug report with my C vendor, I would like to
know what the correct behavior is.

struct S
{
unsigned int a:4;
unsigned int b:16;
};

void foo(void);
void bar(void);

int main(void)
{
struct S s;
s.a = 0;
s.b = 0;

if (s.a - 5 < 0)
foo();
else
bar();

if (s.b - 5 < 0)
foo();
else
bar();

return 0;
}
Carsten Hansen


Nov 14 '05 #94
In article <42***************@yahoo.com>, CBFalconer
<cb********@yahoo.com> writes
Remember, joe q programmer has written "unsigned int" for the type
of the bit field. If he uses the content of that field, he should
expect to get an unsigned int that obeys the laws for unsigned
ints. If he uses that content in some other type, then the value
preserving language of the standard kicks in.


What really concerns me is that a programmer who has carefully used
unsigned int to avoid undefined behaviour in case of overflow gets his
design overruled by the language.

Coupling the promotion rules with the different behaviour on overflow is
a really poor language design. Without that difference (in the
consequences of overflow) I would not have any strong feelings about the
promotion rules, but as they are we get to a ludicrous position that UB
can be implementation dependent.

--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
Nov 14 '05 #95
"yt****@gmail.com" wrote:

I am wondering that in GCC bith cases are "Foo". If I remove bit
fileds in structure and executes, it gives "Bar". Can any one
helps me in explaning why unsigned type is not considering in
presence of bit fileds?.


That's what the argument is about.

Please don't toppost. Your answer belongs after (or intermixed
with) the material to which you reply, with non-germane areas
snipped out.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #96
Keith Thompson wrote:
.... snip ...
Interesting. I just tried it with a number of compilers, and they
all got it right (everything promotes to signed).


Now start playing with the defines in this variant on Jacks test:

#include <stdio.h>

struct nu {
unsigned uc: 8;
unsigned us: 16;
};

#define DELTA 32900 /* 5 or 32900 */
#define INIT -1 /* 0 or -1 */

int main(void)
{
unsigned char uc = INIT;
unsigned short us = INIT;
struct nu nu = { INIT, INIT };

if ((uc - DELTA) < 0) puts("unsigned char ==> signed");
else puts("unsigned char ==> unsigned");
if ((nu.uc - DELTA) < 0) puts("unsigned :8 ==> signed");
else puts("unsigned :8 ==> unsigned");
if ((us - DELTA) < 0) puts("unsigned short ==> signed");
else puts("unsigned short ==> unsigned");
if ((nu.us - DELTA) < 0) puts("unsigned :16 ==> signed");
else puts("unsigned :16 ==> unsigned");
return 0;
}

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
Nov 14 '05 #97
In message <qC**************@robinton.demon.co.uk>
Francis Glassborow <fr*****@robinton.demon.co.uk> wrote:
In article <42***************@yahoo.com>, CBFalconer
<cb********@yahoo.com> writes
Remember, joe q programmer has written "unsigned int" for the type
of the bit field. If he uses the content of that field, he should
expect to get an unsigned int that obeys the laws for unsigned
ints. If he uses that content in some other type, then the value
preserving language of the standard kicks in.


What really concerns me is that a programmer who has carefully used
unsigned int to avoid undefined behaviour in case of overflow gets his
design overruled by the language.


Example?

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #98
In message <ln************@nuthaus.mib.org>
Keith Thompson <ks***@mib.org> wrote:
Jack Klein <ja*******@spamcop.net> writes:
[...]
Amazingly, I just tested this with four compilers, all of which got it
wrong.


Interesting. I just tried it with a number of compilers, and they all
got it right (everything promotes to signed).


Would the two of you care to name the compilers? I'd certainly be interested
to see who's getting it right and wrong.

For the record, Norcroft ARM C gives all signed when in ANSI mode, and all
unsigned when in pcc mode.

--
Kevin Bracey, Principal Software Engineer
Tematic Ltd Tel: +44 (0) 1223 503464
182-190 Newmarket Road Fax: +44 (0) 1728 727430
Cambridge, CB5 8HE, United Kingdom WWW: http://www.tematic.com/
Nov 14 '05 #99
"Kevin Bracey" <ke**********@tematic.com> wrote in message
news:ed****************@tematic.com...
In message <qC**************@robinton.demon.co.uk>
Francis Glassborow <fr*****@robinton.demon.co.uk> wrote:
In article <42***************@yahoo.com>, CBFalconer
<cb********@yahoo.com> writes
Remember, joe q programmer has written "unsigned int" for the type
of the bit field. If he uses the content of that field, he should
expect to get an unsigned int that obeys the laws for unsigned
ints. If he uses that content in some other type, then the value
preserving language of the standard kicks in.


What really concerns me is that a programmer who has carefully used
unsigned int to avoid undefined behaviour in case of overflow gets his
design overruled by the language.


Example?


How about, on a system with USHRT_MAX = 2^16 - 1 and INT_MAX = 2^31 - 1,

unsigned short a = -1, b = -1, c;
c = a * b;

Alex
Nov 14 '05 #100

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

13
by: Amy DBA | last post by:
I've been asked to administer a DB2 V 8 (32-bit install) on a Solaris 64-bit platform. It seems like whomever installed DB2 on the server, goofed for not installing DB2 v8 64 bit. Do I understand...
12
by: Jean-Marc Blaise | last post by:
Hi, Is it worth to use 64-bit DB2 instances on a 32-bit kernel, in terms of: - performance - configuration (go beyond the 256 Mb segment for private mem, 1.75 Gb for Bufferpools) - other ? ...
11
by: JDeats | last post by:
1. Will there be different 64-bit .NET implementations for Intel and AMD 64-bit processors or will they share a common 64-bit CLR? 2. Will .NET managed code compiled for the 32-bit CLR be binary...
58
by: Larry David | last post by:
Ok, first of all, let's get the obvious stuff out of the way. I'm an idiot. So please indulge me for a moment. Consider it an act of "community service".... What does "64bit" mean to your friendly...
4
by: tommydkat | last post by:
Well, I've finally gotten UDB 8.2 FixPak 3 up and running on my HP-UX 11i system, thanks to Mr McBride and IBM support. :) I created a 32-bit instance and that's running just fine. However, I...
14
by: ern | last post by:
Does a function exist to convert a 128-bit hex number to a string?
14
by: =?Utf-8?B?R2Vvcmdl?= | last post by:
Hello everyone, I am using C# to develop DLL using Visual Studio 2005 and .Net 2.0, and I have no idea of how to make my DLL work with applications on 64-bit platform. Above all, I do not...
1
by: Chuck Chopp | last post by:
I have some code that is being built on the following: Windows Server 2003, both 32-bit & 64-bit editions Windows Vista, both 32-bit & 64-bit editions Windows Server 2008, both 32-bit & 64-bit...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.