Bit-fields vs integral promotions

Discussion in 'C Programming' started by Thurston Manson, Aug 23, 2007.

  1. 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 a:4;
    unsigned b:16;
    };

    foo();
    bar();

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

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

    if (s.b - 5 < 0) foo();
    else bar();
    }
     
    Thurston Manson, Aug 23, 2007
    #1
    1. Advertising

  2. Thurston Manson

    CBFalconer Guest

    Thurston Manson 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 a:4;
    > unsigned b:16;
    > };
    >
    > foo();
    > bar();
    >
    > main() {
    > struct S s;
    > s.a = s.b = 0;
    > if (s.a - 5 < 0) foo();
    > else bar();
    > if (s.b - 5 < 0) foo();
    > else bar();
    > }


    This won't even compile. foo and bar are never defined. main
    should return an int (required in C99). The return is missing
    (required in C90). You are comparing signed and unsigned values.
    No compiler bugs have been evidenced.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 23, 2007
    #2
    1. Advertising

  3. Thurston Manson

    Jack Klein Guest

    On Thu, 23 Aug 2007 18:08:29 +0200 (CEST), Thurston Manson
    <> wrote in comp.lang.c:

    > 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 a:4;
    > unsigned b:16;
    > };
    >
    > foo();
    > bar();
    >
    > main()


    Since you mentioned C99, I'll point out that the two declarations and
    the definition of main() above are illegal in C99. Implicit int was
    removed from the language in C99.

    > {
    > struct S s;
    > s.a = s.b = 0;
    >
    > if (s.a - 5 < 0) foo();
    > else bar();
    >
    > if (s.b - 5 < 0) foo();


    Before you file a bug report with your C vendor, I'd suggest
    considering that the "correct behavior" is for the programmer to
    write:

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

    ....or:

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

    ....and make the desired behavior explicit.

    > else bar();
    > }


    This would probably be better asked on comp.std.c, by the way. I'm
    cross posting this reply there, to see what comment it elicits.

    As for an unsigned bit-field holding 16 bits on a platform where int
    has 16 bits, this is quite clear. It must promote to unsigned int,
    therefore "s.b - 5" becomes (unsigned int)(UINT_MAX - 4), otherwise
    known as 65531.

    The promotion of an unsigned int bit-field with fewer bits than the
    number of value bits in a signed int is more controversial.

    Unfortunately, the wording of the C90 standard concerning bit-fields
    is obscure and rather ambiguous. The wording of the C99 standard has
    changed and added more specifics, mainly due to the addition of _Bool
    and the <stdint.h> integer types, but at least it specifically
    mentions bit-fields in the integer promotions. Some feel that it is
    still ambiguous, but I think it is pretty clear.

    I'll start with C99 (which is easier to quote from the PDF file):

    ====
    6.3.1 Arithmetic operands
    6.3.1.1 Boolean, characters, and integers
    1 Every integer type has an integer conversion rank defined as
    follows:
    — No two signed integer types shall have the same rank, even if they
    have the same representation.
    — The rank of a signed integer type shall be greater than the rank of
    any signed integer type with less precision.
    — The rank of long long int shall be greater than the rank of long
    int, which shall be greater than the rank of int, which shall be
    greater than the rank of short int, which shall be greater than the
    rank of signed char.
    — The rank of any unsigned integer type shall equal the rank of the
    corresponding signed integer type, if any.
    — The rank of any standard integer type shall be greater than the rank
    of any extended integer type with the same width.
    — The rank of char shall equal the rank of signed char and unsigned
    char.
    — The rank of _Bool shall be less than the rank of all other standard
    integer types.
    — The rank of any enumerated type shall equal the rank of the
    compatible integer type (see 6.7.2.2).
    — The rank of any extended signed integer type relative to another
    extended signed integer type with the same precision is
    implementation-defined, but still subject to the other rules for
    determining the integer conversion rank.
    — For all integer types T1, T2, and T3, if T1 has greater rank than T2
    and T2 has greater rank than T3, then T1 has greater rank than T3

    2 The following may be used in an expression wherever an int or
    unsigned int may be used:
    — An object or expression with an integer type whose integer
    conversion rank is less than the rank of int and unsigned int.
    — A bit-field of type _Bool, int, signed int, or unsigned int.

    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.

    These are called the integer promotions. All other types are unchanged
    by the integer promotions.
    ====

    Notice the last bullet point in paragraph 2, that specifies that
    bit-fields of int, signed int, unsigned int, and, in C99 only, _Bool,
    participate in the integer promotions. This is followed by the
    definition of integer promotions, namely that if all values of the
    original type are within the range of signed int,

    Next, in C99, we get to the definition of bit-fields, 6.7.2.1 P9:

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

    Now to tie this together, we have 6.2.6.2 P6:

    ====
    The precision of an integer type is the number of bits it uses to
    represent values, excluding any sign and padding bits. The width of an
    integer type is the same but including any sign bit; thus for unsigned
    integer types the two values are the same, while for signed integer
    types the width is one greater than the precision.
    ====

    So in C99, even though "A bit-field of type _Bool, int, signed int, or
    unsigned int" participates in the integer promotions, it is converted
    to signed in if "an int can represent all values of the original
    type", but there has been quite some discussion about whether "the
    original type" means either:

    1. The "original type" of an unsigned int bit-field is unsigned int,
    regardless of the fact that the number of bits used is less than the
    value bits in a signed int, so an unsigned int bit-field always
    promotes to unsigned int. Even though all the values that can
    actually fit into a small unsigned int bit-field are within the range
    of values that an int can hold.

    2. The "original type" is the user-defined "unsigned integer type
    consisting of the specified number of bits."

    There seems to be less ambiguity when precision is factored in. Since
    the unsigned int bit-field is "interpreted" as consisting of the
    specified number of bits, its precision is that number of bits.

    And there is the clear statement that "the rank of a signed integer
    type shall be greater than the rank of any signed integer type with
    less precision" together with "the rank of any unsigned integer type
    shall equal the rank of the corresponding signed integer type."

    So s.a has a precision of 4, and signed int on the implementation you
    specified has a precision of 15, which means it has a lesser rank than
    signed or unsigned int, and therefore should promote to signed int
    because all the values that can fit in an unsigned int with a
    precision of 4 are in the range of signed int.

    There has been some argument that this chain of reasoning falls apart
    because it is based on the word "interpreted", which is not actually
    defined by the standard, at least not as used in this context.

    For C90, things are even muddier.

    The entire section on the integer promotions 6.2.1.1 is:

    ====
    A char, a short int, or an int bit-field, or their signed or
    unsigned varieties, or an object that has enumeration type, may be
    used in an expression wherever an int or unsigned int may be used. 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.
    These are called the integral promotions.

    The integral promotions preserve value including sign. As
    discussed earlier, whether a ``plain'' char is treated as signed is
    implementation-defined.
    =====

    The statement about bit-fields is nearly the same as C99, "A bit-field
    is interpreted as an integral type consisting of the specified number
    of bits."

    C90 makes no mention of "rank", or "precision" for integer types based
    on number of value bits.

    So there are fewer sign posts in C90, all one can go on is one's
    opinion about whether the "original type" of "unsigned: 4:" is
    "unsigned" or an "interpreted" type that can hold the values from 0 to
    16.

    My personal opinion is that the intent in both versions is that an
    unsigned int bit-field with the same number of value bits as a signed
    int, or fewer, should promote to signed int.

    I have to agree with posted sentiments that the normative text of the
    standard does not actually state that conclusively, although one can
    make a stronger case for C99 than for C90.

    As for filing a bug report, don't be surprised if your compiler vendor
    disagrees with you.

    Every compiler I have ever tested this on always promotes unsigned
    bit-fields to unsigned int, regardless of the number of bits. This
    includes at least Microsoft VC++ 6.0 an 2005 Express, Borland C++
    Builder X, Peles C, and MinGW.

    So even if you agree that s.a should promote to signed int, be
    prepared to hear that the standard is ambiguous, especially C90, and
    also that most compilers promote it to unsigned.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Aug 24, 2007
    #3
  4. Thurston Manson

    Chris Torek Guest

    In article <>
    Thurston Manson <> wrote:
    >[assuming 16-bit "int" in the example below]
    >... I would like to know what the correct behavior is.
    >
    >struct S
    >{
    > unsigned a:4;
    > unsigned b:16;
    >};

    [snippage]
    > struct S s;
    > s.a = s.b = 0;
    >
    > if (s.a - 5 < 0) foo();
    > else bar();
    >
    > if (s.b - 5 < 0) foo();
    > else bar();


    Jack Klein has given an accurate (I believe) description of the
    State of the Standard, which I think boils down to "nobody seems
    to know for sure, because compilers don't do what the Standard
    seems to say they should." :) (OK, this is a bit oversimplified.
    Realistically, it is a problem though.)

    Since I am waiting for yet another interminable compile, I will
    take this opportunity to gripe about the C standards here. I think
    C *should* have been defined with the much simpler rule: "in a
    meetup between signed and unsigned, unsigned persists". That is,
    given a narrow unsigned [%] type, and a wider signed type, and an
    operator that has to find a common type for whatever reason, the
    signed type should be converted to unsigned.

    If C worked like this, the answer would be clear: since s.a and
    s.b are both explicitly "unsigned", they would widen to ordinary
    unsigned int, regardless of the relative values of INT_MAX and
    UINT_MAX. Then, since s.a and s.b had value 0, the subtraction
    would always result in (UINT_MAX + 1 - 5), or (UINT_MAX - 4), an
    unsigned number definitely greater than zero, so both tests would
    call foo().

    Unfortunately, to paraphrase someone I might prefer not to paraphrase,
    we have to work with the Standard we have, not the Standard we
    might like or wish to have. :) So in questionable cases like
    this, you are probably best off using casts or temporary variables
    to force whichever interpretation you wnat.

    [%] In order to handle plain char, which may be unsigned (i.e.,
    CHAR_MAX == UCHAR_MAX and CHAR_MIN == 0) but should probably expand
    to plain, i.e., signed, int, I think the rule should apply only to
    things explicitly declared as "unsigned". This probably should
    apply to bitfields as well, since the signedness of bitfields is
    implementation-defined. Note that this would have some annoying
    implications:

    - If CHAR_BIT is 16 or more and CHAR_MAX == UINT_MAX, a plain
    "char" (which is unsigned on this implementation) widens to
    signed "int", which cannot hold all the values in the
    original. (Of course, if you explicitly write "unsigned char",
    it remains unsigned.)

    - Similarly, if the number of bits in a plain "int" is N, the
    bitfield:
    int field:N;
    would widen to a signed int, even if the implementation makes
    "plain" ints in bitfields unsigned. (Again, if you used
    unsigned int field:N;
    it would remain unsigned, because you explicitly used the
    "unsigned" keyword.)

    (But I do not get to dictate how C should work.)
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
     
    Chris Torek, Aug 24, 2007
    #4
  5. Jack Klein wrote:

    >
    > As for an unsigned bit-field holding 16 bits on a platform where int
    > has 16 bits, this is quite clear. It must promote to unsigned int,
    > therefore "s.b - 5" becomes (unsigned int)(UINT_MAX - 4), otherwise
    > known as 65531.


    It's not that clear.
    If signed int can hold all the values of unsigned int (IIRC, there are
    platforms without "native" unsigned arithmetic for which this is the
    case), then, it should be promoted to int.

    --
    You can contact me at <>
     
    André Gillibert, Aug 24, 2007
    #5
  6. Thurston Manson

    Jack Klein Guest

    On Fri, 24 Aug 2007 11:03:54 +0200, "André Gillibert"
    <> wrote in comp.std.c:

    > Jack Klein wrote:
    >
    > >
    > > As for an unsigned bit-field holding 16 bits on a platform where int
    > > has 16 bits, this is quite clear. It must promote to unsigned int,
    > > therefore "s.b - 5" becomes (unsigned int)(UINT_MAX - 4), otherwise
    > > known as 65531.

    >
    > It's not that clear.
    > If signed int can hold all the values of unsigned int (IIRC, there are
    > platforms without "native" unsigned arithmetic for which this is the
    > case), then, it should be promoted to int.


    Please note that I specifically said "on a platform where int has 16
    bits". A platform such as you allude to must have at least 17 bits in
    a signed int.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://c-faq.com/
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Aug 24, 2007
    #6
  7. Thurston Manson

    CBFalconer Guest

    Jack Klein wrote:
    >

    .... snip ...
    >
    > Please note that I specifically said "on a platform where int has
    > 16 bits". A platform such as you allude to must have at least 17
    > bits in a signed int.


    I don't believe you can have such without having a 17 bit unsigned
    int, thus leading to a 18 bit int, and thence to an 18 bit
    unsigned, and ....

    I don't think use of trap bits can affect this. Unsigned to signed
    conversion is always possible because of the modulo unsigned
    arithmetic.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 24, 2007
    #7
  8. Jack Klein wrote:

    > Please note that I specifically said "on a platform where int has 16
    > bits". A platform such as you allude to must have at least 17 bits in
    > a signed int.
    >

    Yep. 18 bits machine did exist... I doubt that there has ever been any 18
    bits machine with 1 padding bit, and one sign bit, without unsigned
    arithmetic.

    Anyway, the standard *permits* that, even if it's practically impossible
    to find any existing platforms that uses such a model.

    --
    You can contact me at <>
     
    André Gillibert, Aug 24, 2007
    #8
  9. CBFalconer wrote:
    > Jack Klein wrote:
    > ... snip ...
    >> Please note that I specifically said "on a platform where int has
    >> 16 bits". A platform such as you allude to must have at least 17
    >> bits in a signed int.

    >
    > I don't believe you can have such without having a 17 bit unsigned
    > int, thus leading to a 18 bit int, and thence to an 18 bit
    > unsigned, and ....
    >
    > I don't think use of trap bits can affect this. Unsigned to signed
    > conversion is always possible


    You may be correct (I do not have time to research the Standard to come
    up with a conclusion) but not for the reason you give.

    because of the modulo unsigned
    > arithmetic.
    >

    Modulo unsigned arithmetic only guarantees that signed to unsigned is
    always possible it has nothing to say about what happens when a
    sufficiently large unsigned value is converted to a signed one.


    --
    Note that robinton.demon.co.uk addresses are no longer valid.
     
    Francis Glassborow, Aug 25, 2007
    #9
  10. CBFalconer said:

    > Thurston Manson wrote:
    >>

    <snip>
    >>
    >> struct S {
    >> unsigned a:4;
    >> unsigned b:16;
    >> };
    >>
    >> foo();
    >> bar();
    >>
    >> main() {
    >> struct S s;
    >> s.a = s.b = 0;
    >> if (s.a - 5 < 0) foo();
    >> else bar();
    >> if (s.b - 5 < 0) foo();
    >> else bar();
    >> }

    >
    > This won't even compile.


    Yes, it will.

    > foo and bar are never defined.


    So? They are implicitly declared by first use. That's enough for
    compilation.

    > main should return an int (required in C99).


    Clearly this is C90 code.

    > The return is missing (required in C90).


    Not so. The return status is undefined, but the behaviour of the program
    is not. In fact, I think that the TU is strictly conforming. I'm not
    saying I approve of omitting the return statement, of course - I don't.

    > You are comparing signed and unsigned values.


    So?

    > No compiler bugs have been evidenced.


    Indeed.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Aug 25, 2007
    #10
  11. Thurston Manson

    CBFalconer Guest

    Francis Glassborow wrote:
    > CBFalconer wrote:
    >

    .... snip ...
    >>
    >> I don't think use of trap bits can affect this. Unsigned to signed
    >> conversion is always possible because of the modulo unsigned
    >> arithmetic.

    >
    > You may be correct (I do not have time to research the Standard to
    > come up with a conclusion) but not for the reason you give.
    >
    > Modulo unsigned arithmetic only guarantees that signed to unsigned
    > is always possible it has nothing to say about what happens when a
    > sufficiently large unsigned value is converted to a signed one.


    No, the standard says that any attempt to store a value outside its
    capacity in a signed int is undefined behaviour.

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>


    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 25, 2007
    #11
  12. CBFalconer wrote:
    > Francis Glassborow wrote:
    >> CBFalconer wrote:
    >>

    > ... snip ...
    >>>
    >>> I don't think use of trap bits can affect this. Unsigned to signed
    >>> conversion is always possible because of the modulo unsigned
    >>> arithmetic.

    >>
    >> You may be correct (I do not have time to research the Standard to
    >> come up with a conclusion) but not for the reason you give.
    >>
    >> Modulo unsigned arithmetic only guarantees that signed to unsigned
    >> is always possible it has nothing to say about what happens when a
    >> sufficiently large unsigned value is converted to a signed one.

    >
    > No, the standard says that any attempt to store a value outside its
    > capacity in a signed int is undefined behaviour.


    C&v, please.
     
    Harald van =?UTF-8?B?RMSzaw==?=, Aug 25, 2007
    #12
  13. CBFalconer writes:
    >Jack Klein wrote:
    >> Please note that I specifically said "on a platform where int has
    >> 16 bits". A platform such as you allude to must have at least 17
    >> bits in a signed int.

    >
    > I don't believe you can have such without having a 17 bit unsigned
    > int, thus leading to a 18 bit int, and thence to an 18 bit
    > unsigned, and ....


    Yes you can. C99 6.2.5p9 (Types):
    "The range of nonnegative values of a signed integer type is a
    subrange of the corresponding unsigned integer type, and the
    representation of the same value in each type is the same."
    Also 6.2.6.2p2 (Integer types):
    "if there are M value bits in the signed type and N in the
    unsigned type, then M <= N". [And p1 says the sign bit is
    not counted as a value bit in signed types.]

    > I don't think use of trap bits can affect this.


    C99 defines trap representations, not trap bits. Padding bits can cause
    a value to be a trap representation (Note 44 in 6.2.6.2 uses a parity
    bit as an example), but I think value and sign bits can too for signed
    types: Negative zero, or -<type>_MAX-1 when <type>_MIN == -<type>_MAX.

    --
    Hallvard
     
    Hallvard B Furuseth, Aug 25, 2007
    #13
  14. CBFalconer <> writes:
    > Francis Glassborow wrote:
    >> CBFalconer wrote:
    >>

    > ... snip ...
    >>>
    >>> I don't think use of trap bits can affect this. Unsigned to signed
    >>> conversion is always possible because of the modulo unsigned
    >>> arithmetic.

    >>
    >> You may be correct (I do not have time to research the Standard to
    >> come up with a conclusion) but not for the reason you give.
    >>
    >> Modulo unsigned arithmetic only guarantees that signed to unsigned
    >> is always possible it has nothing to say about what happens when a
    >> sufficiently large unsigned value is converted to a signed one.

    >
    > No, the standard says that any attempt to store a value outside its
    > capacity in a signed int is undefined behaviour.


    Not quite. Conversion to a signed type, if the value can't be
    represented, yields an implementation-defined result or raises an
    implementation-defined signal. (Overflowing arithmetic operations on
    signed types, on the other hand, invoke undefined behavior.)

    --
    Keith Thompson (The_Other_Keith) <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."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Aug 25, 2007
    #14
  15. Thurston Manson

    CBFalconer Guest

    Hallvard B Furuseth wrote:
    > CBFalconer writes:
    >> Jack Klein wrote:
    >>
    >>> Please note that I specifically said "on a platform where int has
    >>> 16 bits". A platform such as you allude to must have at least 17
    >>> bits in a signed int.

    >>
    >> I don't believe you can have such without having a 17 bit unsigned
    >> int, thus leading to a 18 bit int, and thence to an 18 bit
    >> unsigned, and ....

    >
    > Yes you can. C99 6.2.5p9 (Types):
    > "The range of nonnegative values of a signed integer type is a
    > subrange of the corresponding unsigned integer type, and the
    > representation of the same value in each type is the same."
    > Also 6.2.6.2p2 (Integer types):
    > "if there are M value bits in the signed type and N in the
    > unsigned type, then M <= N". [And p1 says the sign bit is
    > not counted as a value bit in signed types.]
    >
    >> I don't think use of trap bits can affect this.

    >
    > C99 defines trap representations, not trap bits. Padding bits
    > can cause a value to be a trap representation (Note 44 in 6.2.6.2
    > uses a parity bit as an example), but I think value and sign bits
    > can too for signed types: Negative zero, or -<type>_MAX-1 when
    > <type>_MIN == -<type>_MAX.


    Maybe I should just add a note to all my software: No protection
    against M==N in 6.2.6.2p2 is afforded. :)

    --
    Chuck F (cbfalconer at maineline dot net)
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net>



    --
    Posted via a free Usenet account from http://www.teranews.com
     
    CBFalconer, Aug 26, 2007
    #15
  16. Thurston Manson

    Jun Woong Guest

    Jack Klein <> wrote:
    [...]
    > 6.3.1.1 Boolean, characters, and integers

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

    [...]
    >
    > So in C99, even though "A bit-field of type _Bool, int, signed int, or
    > unsigned int" participates in the integer promotions, it is converted
    > to signed in if "an int can represent all values of the original
    > type", but there has been quite some discussion about whether "the
    > original type" means either:
    >
    > 1. The "original type" of an unsigned int bit-field is unsigned int,
    > regardless of the fact that the number of bits used is less than the
    > value bits in a signed int, so an unsigned int bit-field always
    > promotes to unsigned int. Even though all the values that can
    > actually fit into a small unsigned int bit-field are within the range
    > of values that an int can hold.
    >
    > 2. The "original type" is the user-defined "unsigned integer type
    > consisting of the specified number of bits."
    >

    [...]
    >
    > For C90, things are even muddier.
    >

    [...]


    The committee has been clarified their intent through a C90 DR122:

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

    >
    > Every compiler I have ever tested this on always promotes unsigned
    > bit-fields to unsigned int, regardless of the number of bits. This
    > includes at least Microsoft VC++ 6.0 an 2005 Express, Borland C++
    > Builder X, Peles C, and MinGW.
    >


    So if an implementation claiming its conformance to the standard
    ignores the number of bits used for a bit-field of unsigned int type
    in performing the integral promotions, it is not conforming.


    --
    Jun, Woong (woong at icu.ac.kr)
    Samsung Electronics Co., Ltd.

    ``All opinions expressed are mine, and do not represent
    the official opinions of any organization.''
     
    Jun Woong, Aug 29, 2007
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Glen Able
    Replies:
    4
    Views:
    449
    Attila Feher
    Jan 28, 2004
  2. Carsten Hansen

    Bit-fields and integral promotion

    Carsten Hansen, Jan 28, 2005, in forum: C Programming
    Replies:
    117
    Views:
    1,971
    Joe Wright
    Feb 8, 2005
  3. joshc
    Replies:
    7
    Views:
    395
    DHOLLINGSWORTH2
    Feb 26, 2005
  4. Christian Kandeler

    Bit-fields and integral promotion/UACs

    Christian Kandeler, Jan 27, 2006, in forum: C Programming
    Replies:
    10
    Views:
    690
    Alex Fraser
    Jan 28, 2006
  5. Peter

    Integral promotions doubt

    Peter, Mar 24, 2013, in forum: C++
    Replies:
    1
    Views:
    200
    Stefan Ram
    Mar 24, 2013
Loading...

Share This Page