printf() and void *

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Ioannis Vranos

    printf() and void *

    I recall from previous discussions here, that we must cast a non-void
    pointer to void * before printing its value with printf("%p"). Is it
    true, and if yes why?
  • Peter Nilsson

    #2
    Re: printf() and void *

    Harald van D©¦k <true...@gmail. comwrote:
    ... [the] example prints the representation of a function
    pointer, not its value.
    It's value is determined by the representation.
    If multiple function pointer representations exist for
    one value, there is no portable way to print the value
    in such a way that the different representations become
    indistinguishab le.
    How is this any different to the case for %p? The only
    thing you're guaranteed is that if you read via %p you'll
    get a pointer that compares equal to the original.

    The 'hex dump' approach has the same guarantee.

    --
    Peter

    Comment

    • Harald van =?UTF-8?b?RMSzaw==?=

      #3
      Re: printf() and void *

      On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
      Harald van Dijk <true...@gmail. comwrote:
      >... [the] example prints the representation of a function pointer, not
      >its value.
      >
      It's value is determined by the representation.
      Of course, but that's true for all types. Should we start printing 1.01 as
      a series of bytes too, then?
      >If multiple function pointer representations exist for one value, there
      >is no portable way to print the value in such a way that the different
      >representation s become indistinguishab le.
      >
      How is this any different to the case for %p? The only thing you're
      guaranteed is that if you read via %p you'll get a pointer that compares
      equal to the original.
      If you print the same value to printf twice, you can be sure you get the
      same string twice. If you print the representation of two identical values
      twice, you can't be sure you get the same string twice.

      Comment

      • ymuntyan@gmail.com

        #4
        Re: printf() and void *

        On Mar 3, 12:19 am, Harald van D©¦k <true...@gmail. comwrote:
        On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
        Harald van D©¦k <true...@gmail. comwrote:
        ... [the] example prints the representation of a function pointer, not
        its value.
        >
        It's value is determined by the representation.
        >
        Of course, but that's true for all types. Should we start printing 1.01 as
        a series of bytes too, then?
        Isn't it what "binary file formats" is about?
        If multiple function pointer representations exist for one value, there
        is no portable way to print the value in such a way that the different
        representations become indistinguishab le.
        >
        How is this any different to the case for %p? The only thing you're
        guaranteed is that if you read via %p you'll get a pointer that compares
        equal to the original.
        >
        If you print the same value to printf twice, you can be sure you get the
        same string twice. If you print the representation of two identical values
        twice, you can't be sure you get the same string twice.
        You can not be sure that you'll get two identical
        strings from printf("%p\n%p\ n", p, p). printf() is
        "better" only in that scanf() will be able to read
        the string back; the "quality" of output may be
        "worse" or "better" in either case.

        Anyway, it was about function pointers, for which
        printf() doesn't work, so...

        Yevgen

        Comment

        • Harald van =?UTF-8?b?RMSzaw==?=

          #5
          Re: printf() and void *

          On Sun, 02 Mar 2008 23:48:33 -0800, ymuntyan wrote:
          On Mar 3, 12:19 am, Harald van Dijk <true...@gmail. comwrote:
          >On Sun, 02 Mar 2008 19:45:29 -0800, Peter Nilsson wrote:
          Harald van Dijk <true...@gmail. comwrote:
          >... [the] example prints the representation of a function pointer,
          >not its value.
          >>
          It's value is determined by the representation.
          >>
          >Of course, but that's true for all types. Should we start printing 1.01
          >as a series of bytes too, then?
          >
          Isn't it what "binary file formats" is about?
          I meant printing the series of bytes as hexadecimal numbers, which is not
          what binary file formats are about.
          >If multiple function pointer representations exist for one value,
          >there is no portable way to print the value in such a way that the
          >different representations become indistinguishab le.
          >>
          How is this any different to the case for %p? The only thing you're
          guaranteed is that if you read via %p you'll get a pointer that
          compares equal to the original.
          >>
          >If you print the same value to printf twice, you can be sure you get
          >the same string twice. If you print the representation of two identical
          >values twice, you can't be sure you get the same string twice.
          >
          You can not be sure that you'll get two identical strings from
          printf("%p\n%p\ n", p, p).
          The standard states that "the value of the pointer is converted to a
          sequence of printing characters, in an implementation-defined manner."
          This, by my reading, does not allow anything other than the value of the
          pointer to have an effect on the output. In particular, it does not allow
          the representation of the pointer (when multiple representations of the
          same value exist) to have an effect.

          Comment

          • Peter Nilsson

            #6
            Re: printf() and void *

            Barry Schwarz <schwa...@doezl .netwrote:
            ...
            scanf must accept many different kinds of pointers.
            > %s requires a char*, %d requires an [int], etc.
            True.
            > Therefore, it is not possible to have a rule that says
            any pointer in the variadic portion of the argument
            list would be "promoted" to void*.
            Why not?

            [Not that I'd want to see such a rule.]

            --
            Peter

            Comment

            • Barry Schwarz

              #7
              Re: printf() and void *

              On Mon, 3 Mar 2008 18:13:09 -0800 (PST), Peter Nilsson
              <airia@acay.com .auwrote:
              >Barry Schwarz <schwa...@doezl .netwrote:
              >...
              >scanf must accept many different kinds of pointers.
              >> %s requires a char*, %d requires an [int], etc.
              Interesting that your reader didn't quote what I wrote.
              >
              >True.
              >
              >> Therefore, it is not possible to have a rule that says
              >any pointer in the variadic portion of the argument
              >list would be "promoted" to void*.
              >
              >Why not?
              Because then scanf would not be receiving the expected type. Changing
              scanf so this could be done was mentioned two sentences later.
              >
              >[Not that I'd want to see such a rule.]

              Remove del for email

              Comment

              • CBFalconer

                #8
                Re: printf() and void *

                Peter Nilsson wrote:
                Barry Schwarz <schwa...@doezl .netwrote:
                >...
                >scanf must accept many different kinds of pointers.
                >%s requires a char*, %d requires an [int], etc.
                >
                True.
                >
                >Therefore, it is not possible to have a rule that says
                >any pointer in the variadic portion of the argument
                >list would be "promoted" to void*.
                >
                Why not?
                They SHOULD be promoted to void. The type required is spelled out
                by the format string, so they can always be converted back to the
                appropriate form. This is one reason why the format string has to
                agree with the types received. All scanf needs to know is in the
                format, and in the void* pointer.

                --
                [mail]: Chuck F (cbfalconer at maineline dot net)
                [page]: <http://cbfalconer.home .att.net>
                Try the download section.



                --
                Posted via a free Usenet account from http://www.teranews.com

                Comment

                • Morris Dovey

                  #9
                  Re: printf() and void *

                  Richard Heathfield wrote:
                  Code that doesn't rely on /any/ implementation-defined (or unspecified or
                  undefined) behaviour - that is, what the Standard calls a "strictly
                  conforming program" - is maximally portable, but even such "ideal" code
                  depends on the very characteristics of the platform that support its
                  ability to produce output (if indeed it does produce output, which need
                  not apply to library code, of course).
                  Erm, yes. Thank you for making that so clear.

                  ROFL

                  --
                  Morris Dovey
                  DeSoto Solar
                  DeSoto, Iowa USA

                  Comment

                  • Harald van =?UTF-8?b?RMSzaw==?=

                    #10
                    Re: printf() and void *

                    On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
                    Suppose it's a PC with 32-bit pointers, without multiple representations
                    for the same value, where cast to unsigned int and back is well-
                    defined.
                    The following function would be a conforming way to print void* in
                    printf:
                    >
                    void print_pointer(v oid *p)
                    {
                    static unsigned counter;
                    printf("'''%08x %08x'''", (unsigned)p, counter++);
                    }
                    >
                    It prints "extra" here, yes. But that "extra" is not forbidden. I have
                    no idea why one would do that, but it certainly would be conforming. How
                    is appending a number worse than prepending "0x"
                    In your example, what's printed depends on more than the pointer value.
                    The pointer value is what must be formatted. Not the pointer value and
                    some other data.
                    or printing "(nil)"?
                    That's fine. It depends only on the value of the pointer, nothing else.
                    fputc() is different, it doesn't have this "implementa tion-defined
                    manner" freedom.
                    And the *printf functions have no freedom in choosing what data to use to
                    print pointers. They happen to have freedom in choosing how to use that
                    data, but that's a different issue.
                    It "writes the character", not a sequence of characters
                    obtained in an implementation-defined manner.
                    Right. The character is printed. Not the character and some other data.

                    If putchar('e') prints "hello", it has written the character. It also
                    happened to have written other data, but the description of putchar
                    doesn't say it can't.

                    It's clear to both of us this logic is invalid.

                    If printf("%p", p) includes a random number in its output, it has
                    formatted the pointer value. It also happened to have formatted other
                    data, but the description of fprintf doesn't say it can't.

                    I don't seem to be able to convince you this logic is equally invalid.
                    Whether it's allowed to use the bits from the representation, I don't
                    know. I'd think it is, but it's a different story anyway.

                    Comment

                    • ymuntyan@gmail.com

                      #11
                      Re: printf() and void *

                      On Mar 4, 1:08 pm, Harald van D©¦k <true...@gmail. comwrote:
                      On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
                      Suppose it's a PC with 32-bit pointers, without multiple representations
                      for the same value, where cast to unsigned int and back is well-
                      defined.
                      The following function would be a conforming way to print void* in
                      printf:
                      >
                      void print_pointer(v oid *p)
                      {
                      static unsigned counter;
                      printf("'''%08x %08x'''", (unsigned)p, counter++);
                      }
                      >
                      It prints "extra" here, yes. But that "extra" is not forbidden. I have
                      no idea why one would do that, but it certainly would be conforming. How
                      is appending a number worse than prepending "0x"
                      >
                      In your example, what's printed depends on more than the pointer value.
                      The pointer value is what must be formatted. Not the pointer value and
                      some other data.
                      >
                      or printing "(nil)"?
                      >
                      That's fine. It depends only on the value of the pointer, nothing else.
                      And also on the will of implementor who can write "(nil)" or
                      "0" or what else he likes. Anyway, you claim that the format
                      of %p output must not depend on the program state; I claim it
                      may depend on the program state. E.g. implementation could
                      choose the format on startup, like print "(nil)" if program
                      started on Monday and print "0" if program started on other
                      day. Or print "(nil)" when printf is *called* on Monday. Or
                      append a random number.

                      I guess we can just agree to disagree here :)
                      fputc() is different, it doesn't have this "implementa tion-defined
                      manner" freedom.
                      >
                      And the *printf functions have no freedom in choosing what data to use to
                      print pointers. They happen to have freedom in choosing how to use that
                      data, but that's a different issue.
                      >
                      It "writes the character", not a sequence of characters
                      obtained in an implementation-defined manner.
                      >
                      Right. The character is printed. Not the character and some other data.
                      >
                      If putchar('e') prints "hello", it has written the character. It also
                      happened to have written other data, but the description of putchar
                      doesn't say it can't.
                      Description of files says it can't. What's written can be read
                      back and you'll know that more than one or a wrong character was
                      written. If it can't be read, then there is simply nothing to
                      talk about.
                      It's clear to both of us this logic is invalid.
                      >
                      If printf("%p", p) includes a random number in its output, it has
                      formatted the pointer value. It also happened to have formatted other
                      data, but the description of fprintf doesn't say it can't.
                      So printf("%p") *is* different in this respect from putchar().

                      Yevgen

                      Comment

                      • CBFalconer

                        #12
                        Re: printf() and void *

                        Barry Schwarz wrote:
                        Peter Nilsson <airia@acay.com .auwrote:
                        >Barry Schwarz <schwa...@doezl .netwrote:
                        >>...
                        >>scanf must accept many different kinds of pointers.
                        >>%s requires a char*, %d requires an [int], etc.
                        >
                        Interesting that your reader didn't quote what I wrote.
                        Hm. According to mine, it did.

                        --
                        [mail]: Chuck F (cbfalconer at maineline dot net)
                        [page]: <http://cbfalconer.home .att.net>
                        Try the download section.


                        --
                        Posted via a free Usenet account from http://www.teranews.com

                        Comment

                        • Richard Heathfield

                          #13
                          Re: printf() and void *

                          CBFalconer said:
                          Barry Schwarz wrote:
                          >Peter Nilsson <airia@acay.com .auwrote:
                          >>Barry Schwarz <schwa...@doezl .netwrote:
                          >>>...
                          >>>scanf must accept many different kinds of pointers.
                          >>>%s requires a char*, %d requires an [int], etc.
                          >>
                          >Interesting that your reader didn't quote what I wrote.
                          >
                          Hm. According to mine, it did.
                          <sighRead it again, Chuck.

                          --
                          Richard Heathfield <http://www.cpax.org.uk >
                          Email: -http://www. +rjh@
                          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
                          "Usenet is a strange place" - dmr 29 July 1999

                          Comment

                          • Harald van =?UTF-8?b?RMSzaw==?=

                            #14
                            Re: printf() and void *

                            On Tue, 04 Mar 2008 11:38:03 -0800, ymuntyan wrote:
                            On Mar 4, 1:08 pm, Harald van Dijk <true...@gmail. comwrote:
                            >On Tue, 04 Mar 2008 10:52:36 -0800, ymuntyan wrote:
                            It "writes the character", not a sequence of characters obtained in
                            an implementation-defined manner.
                            >>
                            >Right. The character is printed. Not the character and some other data.
                            >>
                            >If putchar('e') prints "hello", it has written the character. It also
                            >happened to have written other data, but the description of putchar
                            >doesn't say it can't.
                            >
                            Description of files says it can't. What's written can be read back and
                            you'll know that more than one or a wrong character was written. If it
                            can't be read, then there is simply nothing to talk about.
                            If stdout hasn't been redirected (either by the program or the
                            environment), it usually can't be read back, yet I'm quite sure that
                            implementations aren't allowed to make putchar('e') print "hello" even if
                            they can determine with absolute certainty that stdout is not by the
                            program.

                            Comment

                            • Harald van =?UTF-8?b?RMSzaw==?=

                              #15
                              Re: printf() and void *

                              On Tue, 04 Mar 2008 20:51:04 +0100, Harald van Dijk wrote:
                              If stdout hasn't been redirected (either by the program or the
                              environment), it usually can't be read back, yet I'm quite sure that
                              implementations aren't allowed to make putchar('e') print "hello" even
                              if they can determine with absolute certainty that stdout is not by the
                              readable ^
                              program.
                              Sorry about that.

                              Comment

                              Working...