printf anomaly

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • indigodfw@yahoo.com

    printf anomaly

    Hi experts

    Consider this piece of code

    unsigned long data = 124; /* Data is actually part of a big struct but
    to simplify */
    printf(" %-5llu ", (unsigned long long)(data*1000 ));


    <memory address say 60000000>: 00000000 00000D77 00000000
    00000000
    0xD77 is 3447

    Assume data is at the beginning of memory address 60000000 and this is
    a big endian machine (MIPS based).
    The compiler is doing two load word from 60000000 and 60000000+4 and
    then multiplying it by 1000 and then prints 3447000 which is not
    expected.

    My understanding is that the 1000 will default to int
    Then it will be promoted to unsigned long (since on our platform long
    and int are of same size)
    then operation will be carried out in unsigned long (result I mean).
    then *result* will be cast to unsigned long long and then it will be
    passed to printf
    (not sure how - this is MIPS based platform) and printf is a variadic
    function.

    I must be missing something or the compiler is broken?

    1.Please help me understand what is going on.
    2.And how can I fix it the right way.

    Please advise.
    Thanks in advance,

  • indigodfw@yahoo.com

    #2
    Re: printf anomaly

    unsigned long data = 0x124
    please ignore the above initialization line in previous post.
    I only wanted to say : the type of data is unsigned long.
    Thanks

    Comment

    • pete

      #3
      Re: printf anomaly

      indigodfw@yahoo .com wrote:
      >
      unsigned long data = 0x124
      >
      please ignore the above initialization line in previous post.
      That line wasn't in your previous post.
      I only wanted to say : the type of data is unsigned long.
      You do need to say more than the type of the data.
      The nature of your complaint is the output of printf,
      which also depends on the value of data.

      Create and post the smallest program that still exhibits your problem.
      Try to use copy and paste facilities or something equivalent,
      instead of posting you recollections
      of what the code may have looked like.

      --
      pete

      Comment

      • Keith Thompson

        #4
        Re: printf anomaly

        indigodfw@yahoo .com writes:
        Consider this piece of code
        >
        unsigned long data = 124; /* Data is actually part of a big struct but
        to simplify */
        printf(" %-5llu ", (unsigned long long)(data*1000 ));
        >
        >
        <memory address say 60000000>: 00000000 00000D77 00000000
        00000000
        0xD77 is 3447
        >
        Assume data is at the beginning of memory address 60000000 and this is
        a big endian machine (MIPS based).
        The compiler is doing two load word from 60000000 and 60000000+4 and
        then multiplying it by 1000 and then prints 3447000 which is not
        expected.
        >
        My understanding is that the 1000 will default to int
        Then it will be promoted to unsigned long (since on our platform long
        and int are of same size)
        then operation will be carried out in unsigned long (result I mean).
        then *result* will be cast to unsigned long long and then it will be
        passed to printf
        (not sure how - this is MIPS based platform) and printf is a variadic
        function.
        >
        I must be missing something or the compiler is broken?
        In a followup you wrote:
        | unsigned long data = 0x124
        |
        | please ignore the above initialization line in previous post.
        | I only wanted to say : the type of data is unsigned long.

        But in your original post, data was initialized to 124, not 0x124.
        The fact that you misquoted your own post doesn't fill me with
        confidence that you've shown us your actual code and data. You show a
        printf call with a format of "%-5llu", but your output is in
        hexadecimal with leading zeros.

        I can't tell from what you posted what the problem might be. Post a
        small complete program that exhibits the problem, along with the
        actual output and what you expected the output to be. Don't re-type
        either the program or the output; copy-and-paste it exactly.

        --
        Keith Thompson (The_Other_Keit h) kst-u@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.

        Comment

        • indigodfw@yahoo.com

          #5
          Re: printf anomaly

          Pete,

          Sure, let me try again.

          printf(" %-5llu ", (unsigned long long)(data*1000 ));

          <16 byts of memory starting at 0x60000000 in hex>:
          00000000 00000D77 00000000 00000000

          data is a unsigned long 4 byte variable starting at 0x60000000
          This is a big endian cpu and address is incrementing for the above
          memory dump.
          0xD77 is 3447 in decimal.

          The output printed is 3447000 in decimal and expected output is zero.
          I would like to understand what is happening.

          Thank you,
          -Sushil

          Comment

          • indigodfw@yahoo.com

            #6
            Re: printf anomaly

            But in your original post, data was initialized to 124, not 0x124.
            The fact that you misquoted your own post doesn't fill me with
            confidence that you've shown us your actual code and data. You show a
            printf call with a format of "%-5llu", but your output is in
            hexadecimal with leading zeros.

            Keith,

            This is running on an embedded system and I can not copy the output.
            What I pasted was dump of memory as seen from a debugger, not a
            printed output.

            Thanks for the reply,


            Comment

            • pete

              #7
              Re: printf anomaly

              indigodfw@yahoo .com wrote:
              >
              Pete,
              >
              Sure, let me try again.
              >
              printf(" %-5llu ", (unsigned long long)(data*1000 ));
              >
              <16 byts of memory starting at 0x60000000 in hex>:
              00000000 00000D77 00000000 00000000
              >
              data is a unsigned long 4 byte variable starting at 0x60000000
              This is a big endian cpu and address is incrementing for the above
              memory dump.
              0xD77 is 3447 in decimal.
              >
              The output printed is 3447000 in decimal and expected output is zero.
              I would like to understand what is happening.
              Post a complete program.

              --
              pete

              Comment

              • Flash Gordon

                #8
                Re: printf anomaly

                indigodfw@yahoo .com wrote, On 22/02/07 02:21:
                >But in your original post, data was initialized to 124, not 0x124.
                >The fact that you misquoted your own post doesn't fill me with
                >confidence that you've shown us your actual code and data. You show a
                >printf call with a format of "%-5llu", but your output is in
                >hexadecimal with leading zeros.
                >
                >
                Keith,
                >
                This is running on an embedded system and I can not copy the output.
                You can copy and paste the program which evidence suggests you did not do.
                What I pasted was dump of memory as seen from a debugger, not a
                printed output.
                Anything could be going on in memory. All we can comment on is what the
                output of the printf call should be on a hosted implementation (if it is
                not hosted it is not even required to provide printf), and then only if
                we are given a *complete* compilable program.
                --
                Flash Gordon

                Comment

                • Jack Klein

                  #9
                  Re: printf anomaly

                  On 21 Feb 2007 17:24:14 -0800, indigodfw@yahoo .com wrote in
                  comp.lang.c:
                  Hi experts
                  >
                  Consider this piece of code
                  >
                  unsigned long data = 124; /* Data is actually part of a big struct but
                  to simplify */
                  I understand that in a later post you day that the initialization line
                  above is not correct, and to just assume that you meant to define
                  "data" as having the type unsigned long.

                  Unfortunately, in your later post and replies to other respondents you
                  do not leave enough context to add additional replies.
                  printf(" %-5llu ", (unsigned long long)(data*1000 ));
                  >
                  >
                  <memory address say 60000000>: 00000000 00000D77 00000000
                  00000000
                  0xD77 is 3447
                  I have no idea what this means, memory dumps are not relevant.
                  Assume data is at the beginning of memory address 60000000 and this is
                  a big endian machine (MIPS based).
                  Why should I assume that? You appear to assume that, and because of
                  that you assume that the compiler is doing something wrong.
                  The compiler is doing two load word from 60000000 and 60000000+4 and
                  then multiplying it by 1000 and then prints 3447000 which is not
                  expected.
                  How the compiler chooses to access the contents of lvalues is up to
                  the compiler. If you are sure it is incorrect you need to contact the
                  compiler supplier.
                  My understanding is that the 1000 will default to int
                  Then it will be promoted to unsigned long (since on our platform long
                  and int are of same size)
                  Your understanding is wrong. The type of the integer literal
                  expression "1000" is int, no default involved. You are also wrong in
                  thinking that the sizes of int and long have anything to do with the
                  automatic conversion. When you perform an operation on a signed int
                  and an unsigned long, the signed int value will be converted to
                  unsigned long regardless of whether the sizes are the same or
                  different.
                  then operation will be carried out in unsigned long (result I mean).
                  then *result* will be cast to unsigned long long and then it will be
                  passed to printf
                  So exactly what are you concerned about? 1000UL * 3447UL = 3447000UL,
                  which is a value that clearly fits in an unsigned long. The cast
                  operator converts this unsigned long long, in which it will surely fit
                  and have the same value.
                  (not sure how - this is MIPS based platform) and printf is a variadic
                  function.
                  >
                  I must be missing something or the compiler is broken?
                  We're missing something, namely the information that you did not
                  provide. Don't show us a hexadecimal dump of what you think is the
                  relevant part of memory, that is irreverent.

                  Are you claiming that the value of "data" is not 3447? How do you
                  know?

                  Show us the output of this code:

                  printf("%lu", data);
                  printf("%llu", (unsigned long long)(data*1000 ))

                  1.Please help me understand what is going on.
                  2.And how can I fix it the right way.
                  Even better, show us the structure definition and how the object is
                  actually accessed in the code, without the simplification.

                  I have seen cases where an access to a structure member actually
                  access the wrong bytes of the object. This is most common when people
                  play games with pointers and make mistakes or have incorrect
                  assumptions, but there are other possible causes.

                  --
                  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.l earn.c-c++

                  Comment

                  • Dietmar Schindler

                    #10
                    Re: printf anomaly

                    indigodfw@yahoo .com wrote:
                    Consider this piece of code
                    >
                    unsigned long data = 124; /* Data is actually part of a big struct but
                    to simplify */
                    printf(" %-5llu ", (unsigned long long)(data*1000 ));
                    >
                    <memory address say 60000000>: 00000000 00000D77 00000000
                    00000000
                    0xD77 is 3447
                    >
                    Assume data is at the beginning of memory address 60000000 and this is
                    a big endian machine (MIPS based).
                    The compiler is doing two load word from 60000000 and 60000000+4 and
                    then multiplying it by 1000 and then prints 3447000 which is not
                    expected.
                    >
                    My understanding is that the 1000 will default to int
                    Then it will be promoted to unsigned long (since on our platform long
                    and int are of same size)
                    then operation will be carried out in unsigned long (result I mean).
                    then *result* will be cast to unsigned long long and then it will be
                    passed to printf
                    (not sure how - this is MIPS based platform) and printf is a variadic
                    function.
                    >
                    I must be missing something or the compiler is broken?
                    >
                    1.Please help me understand what is going on.
                    What you are missing could be the knowledge that sizeof (unsigned long)
                    is 8.
                    2.And how can I fix it the right way.
                    There would be nothing wrong and nothing to fix.

                    --
                    DPS

                    Comment

                    • Joe Wright

                      #11
                      Re: printf anomaly

                      indigodfw@yahoo .com wrote:
                      Pete,
                      >
                      Sure, let me try again.
                      >
                      printf(" %-5llu ", (unsigned long long)(data*1000 ));
                      >
                      <16 byts of memory starting at 0x60000000 in hex>:
                      00000000 00000D77 00000000 00000000
                      >
                      data is a unsigned long 4 byte variable starting at 0x60000000
                      This is a big endian cpu and address is incrementing for the above
                      memory dump.
                      0xD77 is 3447 in decimal.
                      >
                      The output printed is 3447000 in decimal and expected output is zero.
                      I would like to understand what is happening.
                      >
                      So data occupies 8 bytes. 0x0000000000000 d77 which is 3447 and when
                      multiplied by 1000 yields 3447000. What's the problem?

                      --
                      Joe Wright
                      "Everything should be made as simple as possible, but not simpler."
                      --- Albert Einstein ---

                      Comment

                      Working...