Thread: practical c programming - oreilly problem ?

  1. #16
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    All operations are promoted to the highest involved type during the operation, and arithmetics (but I think not bit stuff) is performed with a minimum type of int.

    What does that mean? Well, Dave_Sinkula mentioned the problem, but apparently didn't explain it enough.

    So let's activate the human debugger and get moving
    const int HIGH_SPEED = (1<<7);
    -> HIGH_SPEED = binary 00000000 00000000 00000000 10000000
    const int DIRECT_CONNECT = (1<<8);
    -> DIRECT_CONNECT = binary 00000000 00000000 00000001 00000000
    char flags = 0;
    -> flags = binary 00000000
    flags |= HIGH_SPEED;
    -> Operation performed on integers. flags is fetched and promoted to 4 0-bytes. HIGH_SPEED is or-ed in, resulting in this:
    -> binary 00000000 00000000 00000000 10000000 = decimal 128
    -> Truncation to char (which is signed) is outside of the range (CHAR_MAX is 127), implementation-defined behaviour.
    -> As MS happens to do it, the result is bit-pattern conversion, thus flags results in
    -> binary 10000000 = decimal -128
    flags |= DIRECT_CONNECT;
    -> Again, flags is promoted. You can see the problem here for the first time, although it has no efffect yet.
    -> Promotion from signed type to signed type always preserves value, thus the promoted value is -128 too, in 4 bytes:
    -> binary 11111111 11111111 11111111 10000000
    -> The or-ing has no effect, the result is the same, truncation is defined this time, as -128 is in range
    -> flags = binary 10000000 = decimal -128
    if((flags & HIGH_SPEED) != 0)
    -> flags again needs to be promoted. The problem occurs again and again has no effect.
    if((flags & DIRECT_CONNECT) != 0)
    -> flags again promoted.
    -> ((int)flags) = binary 11111111 11111111 11111111 10000000 = decimal -128
    -> DIRECT_CONNECT = binary 00000000 00000000 00000001 00000000
    -> AND = binary 00000000 00000000 00000001 00000000 != 0

    I hope the problem is clear now. There are two parts to the solution.
    First, ALWAYS use UNSIGNED types for bit fields and bit constants.
    Second, ALWAYS use the SAME type for bit fields and their associated constants.
    Last edited by CornedBee; 12-07-2004 at 12:22 PM.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  2. #17
    * S T U D E N T *
    Join Date
    Oct 2003
    Posts
    30

    Thumbs up

    Guys the problem has been solved! Thankyou for all your support. Something i didn't mention (because i didn't think it necessary) was that I was working on a UNIX machine. I have just been informed by a University colleague that an int on a UNIX machine is 32-bit long and therefore to resolve the situation i should either set DIRECT_CONNTECT to be (1<<32) or (and this is what i did) initialise HIGH_SPEED and DIRECT_CONNECT as chars and not ints. the compiler warns about overflow and then only outputs "High speed set" .... BRILLIANT!

    guyattc2-practical_c3-> gcc -o high high.c
    high.c:6: warning: overflow in implicit constant conversion
    guyattc2-practical_c3-> high
    High speed set

    Thanks once again! I may now sleep at night! hehe

    --CHriS
    'rm -fr /bin/laden'
    'kill all'

  3. #18
    Registered User
    Join Date
    Oct 2001
    Posts
    2,934
    >an int on a UNIX machine is 32-bit long
    And also on most PC's. The problem is you didn't use unsigned char for flags. Then it would only print "high speed set".

  4. #19
    * S T U D E N T *
    Join Date
    Oct 2003
    Posts
    30

    Thumbs up

    Quote Originally Posted by swoopy
    The problem is you didn't use unsigned char for flags.
    Not me, Mr Steve Oualline, Practical C Programming by O'Reilly.

    --CHriS
    'rm -fr /bin/laden'
    'kill all'

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Need help understanding a problem
    By dnguyen1022 in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2009, 04:21 PM
  2. Memory problem with Borland C 3.1
    By AZ1699 in forum C Programming
    Replies: 16
    Last Post: 11-16-2007, 11:22 AM
  3. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  4. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM