How to answer Printf Interview question

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • connintel
    New Member
    • May 2010
    • 1

    #1

    How to answer Printf Interview question

    One of the recent interview I have been asked to give the output of following program:

    Code:
    void main()
    {
     int i = 5;
     printf(" %d %d %d %d ", ++i,i++,--i,++i);
    }
    Result is : 7 5 7 7.

    I couldnt answer correctly but I dont know how it gets to 7 5 7 7, what is the logic does printf flows to print the above values of i.
    Last edited by Niheel; May 26 '10, 02:13 PM. Reason: code tags
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    main returns void, this is undefined behaviour.

    If main returned int then this would still exhibit undefined behaviour because of this clause in the standard

    ""Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored."

    anything breaking this clause is undefined behaviour and this code does break it because it tries to modify i 4 times between sequence points.

    Since the behaviour is undefined the output can be anything.

    On a related point it should be noted that the order of evaluation of parameters to a function is platform dependent.


    So the standard correct answer to the question is "anything"

    Comment

    • donbock
      Recognized Expert Top Contributor
      • Mar 2008
      • 2427

      #3
      The result probably corresponds to one of the 24 permutations of the four arguments. However, the Standard allows a compiler to do anything when a program triggers undefined behavior: blank the screen, reformat your hard drive, blow up an offshore oil well, remove all the ozone from the atmosphere, change Pluto back into a planet, throw the Sun into a black hole, ... it is all fair game.

      I hope this explains why Banfa is always so adamant that undefined behavior be avoided.

      Comment

      • constablebrew
        New Member
        • Jun 2010
        • 3

        #4
        As I understand it, the following should be well defined:
        Code:
        void main()
        {
         int i = 5;
         printf(" %d ", ++i);
         printf(" %d ", i++);
         printf(" %d ", --i);
         printf(" %d ", ++i);
        }
        However, would there be a better way of doing this? Maybe this way?:
        Code:
        void main()
        {
         int i = 5;
         int j = ++i;
         int k = i++;
         int l = --i;
         int m = ++i;
         printf(" %d %d %d %d ", j,k,l,m);
        }

        Comment

        • donbock
          Recognized Expert Top Contributor
          • Mar 2008
          • 2427

          #5
          I agree -- your first code snippet does not invoke any undefined behavior, so its output is predictable.

          I can't think of any good reason to prefer one code snippet over the other. I suppose the first snippet is marginally better because you might fool yourself if the order of variables in the printf wasn't the same as the order the variables were assigned. That is, the second snippet presents the possibility that you type something like this:
          Code:
          void main() 
          { 
           int i = 5; 
           int j = ++i; 
           int k = i++; 
           int l = --i; 
           int m = ++i; 
           printf(" %d %d %d %d ", k,j,l,m); 
          }

          Comment

          • constablebrew
            New Member
            • Jun 2010
            • 3

            #6
            My intentions were to avoid multiple printf calls. I don't understand why, but I have been told in the past that system calls should always be reduced to as few as possible.

            Comment

            • donbock
              Recognized Expert Top Contributor
              • Mar 2008
              • 2427

              #7
              ... as few as possible, but no fewer.

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                To paraphrase Mr Albert Einstein

                Comment

                • Banfa
                  Recognized Expert Expert
                  • Feb 2006
                  • 9067

                  #9
                  P.S. system calls can take a while to execute because you have to access the system and because you may have to wait for someone else to finish accessing the same system.

                  So reducing the number of system calls, in theory, makes the program more efficient.

                  Comment

                  • donbock
                    Recognized Expert Top Contributor
                    • Mar 2008
                    • 2427

                    #10
                    By the way, another way to get unpredictable results is to access a volatile variable more than once in a single statement.

                    I once worked with an input device that provided a 32-bit data word via a 16-bit data bus. The first read gave the upper word and the second read was the lower word. My first effort was:
                    Code:
                    const unsigned short * const pDevice = <some address>;
                    ...
                    unsigned long value;
                    value = (((unsigned long)*pDevice) << 16) | *pDevice;
                    Unfortunately for me, this code appeared to work fine. Fortunately I always pass my code through a static checker. It warned me that I had relied on implementation-specific behavior -- that is, I had assumed the left-most pointer dereference happened first. I changed my code to this:
                    Code:
                    const unsigned short * const pDevice = <some address>;
                    ...
                    unsigned long value;
                    value = ((unsigned long)*pDevice) << 16;
                    value |= *pDevice;

                    Comment

                    Working...