Thread: c puzzle

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User ralu.'s Avatar
    Join Date
    Feb 2009
    Location
    Bucharest, RO
    Posts
    32

    c puzzle

    For those who like to keep your mind sharp or for those who want to test their skills in programming here is an interesting C programming bug:
    Code:
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
      while(1) {
        fprintf(stdout, "out \t");
        fprintf(stderr, "err \t");
        sleep(1);
      }
        
      return 0;
    }
    This program will not print on the screen "out".. can you say why?
    I have stopped reading Stephen King novels. Now I just read C code instead.

  2. #2
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by ralu. View Post
    here is an interesting C programming bug:
    It's not a bug!

    standard out is buffered output, and that buffer is only flushed when:
    a) it's full
    b) you call fflush()
    c) you print a \n

    QuantumPete

    edit:
    Try this to illustrate:
    Code:
    #include <stdio.h>
    #include <unistd.h>
    
    int main(int argc, char **argv)
    {
      int num = 5;
      while(num--) {
        fprintf(stdout, "out \t");
        fprintf(stderr, "err \t");
        sleep(1);
      }
      fprintf (stdout, "\n");  
      return 0;
    }
    Last edited by QuantumPete; 03-05-2009 at 03:39 AM. Reason: Added illustration program
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    And of course, it's all depending on the implementation of the C library. Sure, stderr is DEFINED as unbuffered, whilst stdout is buffered, but there is nothing saying that stdout has to have a buffer bigger than 1 character.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User ralu.'s Avatar
    Join Date
    Feb 2009
    Location
    Bucharest, RO
    Posts
    32
    Here it is another interesting problem:

    Code:
    #include <stdio.h>
    
    int main(int argc, char **argv)
    {
      int i;
      double num = 0.0;
    
      for(i = 0; i < 10; i++)
        num = num + 0.1;
    
      if(num == 1.0)
        printf("num == 1.0\n");
      else
        printf("num != 1.0\n");
    
      return 0;
    }
    I have stopped reading Stephen King novels. Now I just read C code instead.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It's not interesting, it's a known fact of 0.1 being one of many numbers that can't be stored PRECISELY in the standard binary floating point formats. It becomes 0.09999999999999999999999 when you translate it back to decimal (the number of nines depend on the length of the binary format, and the actual printout with lots of digits may show some "random" values at the end, depending how the bits at the end match up with the digits printed).

    Obviously, adding 0.09999999... together ten times leaves you with a number similar to 0.9999999... which is not precisely 1.0, so a comparison on a bit-level will see them as different numbers, even if a rounded printout will not!

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User ralu.'s Avatar
    Join Date
    Feb 2009
    Location
    Bucharest, RO
    Posts
    32
    matsp, QuantumPete i was not expecting the pb to be interesting for you, cause i know it's not... But on this forum are many newbies for whom this is interesting: the result is not what they expect it to be.

    Maybe this you'll find a little more interesting:

    Code:
    void send(register char *to, register char *from, register int count)
    {
      register int num = (count + 7) / 8;
    
      switch(count % 8){
      case 0: do { *to++ = *from++;
        case 7:  *to++ = *from++;
        case 6: *to++ = *from++;
        case 5: *to++ = *from++;
        case 4: *to++ = *from++;
        case 3: *to++ = *from++;
        case 2: *to++ = *from++;
        case 1: *to++ = *from++;
        } while( --num > 0);
      }
    I have stopped reading Stephen King novels. Now I just read C code instead.

  7. #7
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by ralu. View Post
    Here it is another interesting problem:
    Well, no. It's not an interesting problem, it's a floating point inaccuracy, which every programmer should be aware of. Just like buffered stdout. These are not hidden issues that you might never need to know about. This is stuff that anyone who seriously develops software in C has to know!

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  8. #8
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    How about this for a puzzle. What does the following print out on your console and more importantly, why?

    Code:
    #include <stdio.h>
    int main (void)
    {
        int n = 0;
        for (n = 0; n <= 1; ++n) 
        {
            printf ("%d", n);
            fork();
        }
        return 0;
    }
    QuantumPete
    Last edited by QuantumPete; 03-05-2009 at 10:25 AM. Reason: corrected code
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by QuantumPete View Post
    How about this for a puzzle. What does the following print out on your console and more importantly, why?

    Code:
    #include <stdio.h>
    int main (void)
    {
        int n = 0;
        for (n = 0; n <= 1; ++n )
        {
            printf ("%d", n);
            fork();
        }
        return 0;
    }
    QuantumPete
    Did you mean the amended code above? As your code won't compile...

    And I have a fair idea what it will print...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by matsp View Post
    Did you mean the amended code above? As your code won't compile...

    And I have a fair idea what it will print...

    --
    Mats
    Yes, sorry, I've corrected my post. So used to using i as an iterator
    Anyone want to venture a guess?

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
    011
    (Although it could be 101 - since there is nothing determining which of the two threads run first, and thus which order the output is, child or parent).

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by matsp View Post
    Code:
    011
    (Although it could be 101 - since there is nothing determining which of the two threads run first, and thus which order the output is, child or parent).

    --
    Mats
    Nope, neither of those is correct.

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by QuantumPete View Post
    How about this for a puzzle. What does the following print out on your console and more importantly, why?

    Code:
    #include <stdio.h>
    int main (void)
    {
        int n = 0;
        for (n = 0; n <= 1; ++n) 
        {
            printf ("%d", n);
            fork();
        }
        return 0;
    }
    QuantumPete
    As to why the output is 01010101 when it's buffered; fork() duplicates the stdout buffer in the child process and their exit is equivalent to calling fflush(stdout) in each of the four distinct processes. That's why the buffer containing "01" is printed out 4 times. When stdout is flushed, the same program prints out 011.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. The puzzle again...Swapping elements of 2D array
    By crazygopedder in forum C Programming
    Replies: 44
    Last Post: 11-05-2008, 01:53 PM
  2. Replies: 12
    Last Post: 06-06-2008, 05:26 PM
  3. Crossword Puzzle Program
    By Loctan in forum C++ Programming
    Replies: 2
    Last Post: 07-31-2006, 11:08 PM
  4. Solution to Google Puzzle 3,3,8,8=24
    By LuckY in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 06-01-2006, 09:12 AM