main function address

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

    #16
    Re: main function address

    Lew Pitcher wrote:[color=blue]
    >
    > -----BEGIN PGP SIGNED MESSAGE-----
    > Hash: SHA1
    >
    > pete wrote:
    > | Martin Dickopp wrote:
    > |
    > |>Lew Pitcher <lpitcher@sympa tico.ca> writes:
    > |>
    > |>
    > |>>#include <stdio.h>
    > |>>#include <stdlib.h>
    > |>>
    > |>>int main(void)
    > |>>{
    > |>> printf("main() at %p\n",(void *)&main);
    > |>>
    > |>> return EXIT_SUCCESS;
    > |>>}
    > |>
    > |>Is the cast to `void *' valid?
    > |
    > |
    > | No.
    > |
    > | In N869, it's one of the common extensions.
    > |
    > | J.5.7 Function pointer casts
    > | [#2] A pointer to a function may be cast to a pointer to an
    > | object or to void, allowing a function to be inspected or
    > | modified (for example, by a debugger) (6.5.4).
    > |
    > | ... which makes it more obviously not part of standard C.
    >
    > In 9989-1999 (admittedly, just the draft C99 standard, and not the
    > /actual standard itself), the printf() function documentation in
    > 7.19.6.3 refers the reader to the fprintf() documentation for a
    > description of it's input. The fprintf() documentation in 7.19.6.1 says
    > of the %p format
    >
    > ~ p The argument shall be a pointer to void. The value of the pointer is
    > ~ converted to a sequence of printing characters, in an
    > ~ implementation-defined manner.
    >
    > So, to satisfy the %p format character, the argument to
    > fprintf()/printf() /must/ be a "pointer to void". Since main is a
    > "pointer to function returning int", and not a "pointer to void", I
    > interpreted the documentation as requiring a cast to void pointer.[/color]

    I interpret it as meaning that printing the address of a function
    isn't something that you are guaranteed to be able to do.

    --
    pete

    Comment

    • Leor Zolman

      #17
      Re: main function address

      On Wed, 07 Apr 2004 07:47:04 -0400, Lew Pitcher <Lew.Pitcher@td .com> wrote:
      ..[color=blue]
      >
      >In 9989-1999 (admittedly, just the draft C99 standard, and not the
      >/actual standard itself), the printf() function documentation in
      >7.19.6.3 refers the reader to the fprintf() documentation for a
      >description of it's input. The fprintf() documentation in 7.19.6.1 says
      >of the %p format
      >
      >~ p The argument shall be a pointer to void. The value of the pointer is
      >~ converted to a sequence of printing characters, in an
      >~ implementation-defined manner.
      >
      >So, to satisfy the %p format character, the argument to
      >fprintf()/printf() /must/ be a "pointer to void". Since main is a
      >"pointer to function returning int", and not a "pointer to void", I
      >interpreted the documentation as requiring a cast to void pointer.[/color]

      Curious -- I've never considered how implicit conversion rules ought to
      play out in the arena of variadic functions... on one hand, pointers to
      /anything/ implicitly convert to pointer-to-void, but on the other hand
      there's no declaration for the receiving pointer-to-void.

      Or, does the implicit conversion apply when the pointer value is extracted
      and cast to void * in the receiving function?
      -leor

      --
      Leor Zolman --- BD Software --- www.bdsoft.com
      On-Site Training in C/C++, Java, Perl and Unix
      C++ users: Download BD Software's free STL Error Message Decryptor at:
      An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

      Comment

      • Dan Pop

        #18
        Re: main function address

        In <W6Jcc.5205$BF2 .654200@news20. bellglobal.com> Lew Pitcher <lpitcher@sympa tico.ca> writes:
        [color=blue]
        >~ printf("main() at %p\n",(void *)&main);[/color]
        ^^^^^^^^^^^^^
        Undefined behaviour. The standard doesn't define conversions between
        function pointers and incomplete or object pointer types. And there is no
        guarantee that the type pointer to void is wide enough to be able to
        represent the result of such a conversion.

        6.3.2.3 Pointers

        1 A pointer to void may be converted to or from a pointer to any
        incomplete or object type...
        ^^^^^^^^^^^^^^^ ^^^^^^^^^^

        7 A pointer to an object or incomplete type may be converted to
        a pointer to a different object or incomplete type...

        8 A pointer to a function of one type may be converted to a pointer
        to a function of another type and back again; the result shall
        compare equal to the original pointer...

        Dan
        --
        Dan Pop
        DESY Zeuthen, RZ group
        Email: Dan.Pop@ifh.de

        Comment

        • Dan Pop

          #19
          Re: main function address

          In <cunoeq4dxe4.fs f@zero-based.org> Martin Dickopp <expires-2004-05-31@zero-based.org> writes:
          [color=blue]
          >Lew Pitcher <lpitcher@sympa tico.ca> writes:
          >[color=green]
          >> #include <stdio.h>
          >> #include <stdlib.h>
          >>
          >> int main(void)
          >> {
          >> printf("main() at %p\n",(void *)&main);
          >>
          >> return EXIT_SUCCESS;
          >> }[/color]
          >
          >Is the cast to `void *' valid? I cannot find anything in the standard
          >which allows a pointer to a function to be converted to type `void *'.[/color]

          It is syntactically valid, but devoid of any semantics, therefore it is
          a case of undefined behaviour due to lack of specification.

          One can replace unconditionally invoking undefined behaviour by
          conditionally invoking undefined behaviour this way:

          unsigned long address = (unsigned long)main;
          printf("main() at %lx\n", address);

          This invokes undefined behaviour *only* if the address of main cannot
          be represented as an unsinged long:

          6 Any pointer type may be converted to an integer type. Except as
          previously specified, the result is implementation-defined. If the
          result cannot be represented in the integer type, the behavior
          is undefined. The result need not be in the range of values of
          ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^ ^^^
          any integer type.
          ^^^^^^^^^^^^^^^ ^^

          C99 users may want to use unsigned long long for this purpose, to increase
          their chances of avoiding undefined behaviour. However, the language
          doesn't guarantee the existence of a solution to this problem (the AS/400
          programmers know why ;-)

          Dan
          --
          Dan Pop
          DESY Zeuthen, RZ group
          Email: Dan.Pop@ifh.de

          Comment

          • Dan Pop

            #20
            Re: main function address

            In <4073d688.70138 0969@news.indiv idual.net> rlb@hoekstra-uitgeverij.nl (Richard Bos) writes:
            [color=blue]
            >Martin Dickopp <expires-2004-05-31@zero-based.org> wrote:
            >[color=green]
            >> Lew Pitcher <lpitcher@sympa tico.ca> writes:
            >>[color=darkred]
            >> > #include <stdio.h>
            >> > #include <stdlib.h>
            >> >
            >> > int main(void)
            >> > {
            >> > printf("main() at %p\n",(void *)&main);
            >> >
            >> > return EXIT_SUCCESS;
            >> > }[/color]
            >>
            >> Is the cast to `void *' valid?[/color]
            >
            >No. Mind you, there is no better way to print the address of a function,
            >either.[/color]

            There is, even if you can't figure it out...
            [color=blue]
            >Where this works, it works; where it doesn't, nothing else is likely to.[/color]

            How do you know?

            Dan
            --
            Dan Pop
            DESY Zeuthen, RZ group
            Email: Dan.Pop@ifh.de

            Comment

            • Martin Dickopp

              #21
              Re: main function address

              pete <pfiland@mindsp ring.com> writes:
              [color=blue]
              > Lew Pitcher wrote:[color=green]
              >>
              >> -----BEGIN PGP SIGNED MESSAGE-----
              >> Hash: SHA1
              >>
              >> pete wrote:
              >> | Martin Dickopp wrote:
              >> |
              >> |>Lew Pitcher <lpitcher@sympa tico.ca> writes:
              >> |>
              >> |>
              >> |>>#include <stdio.h>
              >> |>>#include <stdlib.h>
              >> |>>
              >> |>>int main(void)
              >> |>>{
              >> |>> printf("main() at %p\n",(void *)&main);
              >> |>>
              >> |>> return EXIT_SUCCESS;
              >> |>>}
              >> |>
              >> |>Is the cast to `void *' valid?
              >> |
              >> |
              >> | No.
              >> |
              >> | In N869, it's one of the common extensions.
              >> |
              >> | J.5.7 Function pointer casts
              >> | [#2] A pointer to a function may be cast to a pointer to an
              >> | object or to void, allowing a function to be inspected or
              >> | modified (for example, by a debugger) (6.5.4).
              >> |
              >> | ... which makes it more obviously not part of standard C.
              >>
              >> In 9989-1999 (admittedly, just the draft C99 standard, and not the
              >> /actual standard itself), the printf() function documentation in
              >> 7.19.6.3 refers the reader to the fprintf() documentation for a
              >> description of it's input. The fprintf() documentation in 7.19.6.1 says
              >> of the %p format
              >>
              >> ~ p The argument shall be a pointer to void. The value of the pointer is
              >> ~ converted to a sequence of printing characters, in an
              >> ~ implementation-defined manner.
              >>
              >> So, to satisfy the %p format character, the argument to
              >> fprintf()/printf() /must/ be a "pointer to void". Since main is a
              >> "pointer to function returning int", and not a "pointer to void", I
              >> interpreted the documentation as requiring a cast to void pointer.[/color]
              >
              > I interpret it as meaning that printing the address of a function
              > isn't something that you are guaranteed to be able to do.[/color]

              So do I. You certainly cannot do it with the `%p' specifier. 6.3.2.3#1
              makes it quite clear that only pointers to incomplete or object type can
              be converted to `void *'.

              Martin


              --
              ,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
              / ,- ) http://www.zero-based.org/ ((_/)o o(\_))
              \ `-' `-'(. .)`-'
              `-. Debian, a variant of the GNU operating system. \_/

              Comment

              • Yakov Lerner

                #22
                Re: main function address

                Richard Bos wrote:
                [color=blue]
                > Martin Dickopp <expires-2004-05-31@zero-based.org> wrote:[color=green]
                >>Lew Pitcher <lpitcher@sympa tico.ca> writes:[color=darkred]
                >>>#include <stdio.h>
                >>>#include <stdlib.h>
                >>>
                >>>int main(void)
                >>>{
                >>> printf("main() at %p\n",(void *)&main);
                >>>
                >>> return EXIT_SUCCESS;
                >>>}[/color]
                >>
                >>Is the cast to `void *' valid?[/color]
                >
                > No. Mind you, there is no better way to print the address of a function,
                > either. Where this works, it works; where it doesn't, nothing else is
                > likely to.[/color]

                Yes there is a better way.
                The code below will still print the binary representation of the
                address of the function where %p won't. Even if
                sizeof(int(*)() ) is bigger than sizeof(void*).

                The trick is that even when you might not convert function ptr
                to void*, nobody said you cannot convert the (&fptr)
                to the (void*) :-), see below :

                /* dump address of the function no matter whether it can be
                * converted to void* or not */
                #include <stdio.h>
                #include <stdlib.h>

                typedef int (*fptr_t)();
                void dump_hex( FILE* out, void* p, int len)
                {
                unsigned char *pb = p;
                int i;
                for(i=0; i < len; i++)
                printf("%02X", 0xFF & (unsigned int)pb[i] );
                }

                void dump_function_a ddr(const char* fname, fptr_t fptr) {
                printf("functio n %s() is at [", fname);
                dump_hex( stdout, (void*)&fptr, sizeof(fptr) );

                /* nb: you might not convert &main to void*, but */
                /* nobody said we cannot convert '&fptr' to void* :-) */

                printf("]\n");
                }

                int main(void)
                {
                dump_function_a ddr("main", main );

                return EXIT_SUCCESS;
                }


                --
                Yakov

                Comment

                • CBFalconer

                  #23
                  Re: main function address

                  Lew Pitcher wrote:[color=blue]
                  > pete wrote:
                  >| Martin Dickopp wrote:
                  >|>Lew Pitcher <lpitcher@sympa tico.ca> writes:
                  >|>
                  >|>> #include <stdio.h>
                  >|>> #include <stdlib.h>
                  >|>>
                  >|>> int main(void)
                  >|>> {
                  >|>> printf("main() at %p\n",(void *)&main);
                  >|>>
                  >|>> return EXIT_SUCCESS;
                  >|>> }
                  >|>
                  >|> Is the cast to `void *' valid?
                  >|
                  >| No.
                  >|
                  >| In N869, it's one of the common extensions.
                  >|
                  >| J.5.7 Function pointer casts
                  >| [#2] A pointer to a function may be cast to a pointer to
                  >| an object or to void, allowing a function to be inspected
                  >| or modified (for example, by a debugger) (6.5.4).
                  >|
                  >| ... which makes it more obviously not part of standard C.
                  >
                  > In 9989-1999 (admittedly, just the draft C99 standard, and not
                  > the /actual standard itself), the printf() function documentation
                  > in 7.19.6.3 refers the reader to the fprintf() documentation for
                  > a description of it's input. The fprintf() documentation in
                  > 7.19.6.1 says of the %p format
                  >
                  > ~ p The argument shall be a pointer to void. The value of the
                  > ~ pointer is converted to a sequence of printing characters, in
                  > ~ an implementation-defined manner.
                  >
                  > So, to satisfy the %p format character, the argument to
                  > fprintf()/printf() /must/ be a "pointer to void". Since main is a
                  > "pointer to function returning int", and not a "pointer to void", I
                  > interpreted the documentation as requiring a cast to void pointer.[/color]

                  A better interpretation is that you may not be able to pass the
                  address of a function to printf. What if you are executing on a
                  system that dynamically loads and unloads functions, for example.
                  That address might be a tape volume name and offset, and require
                  operator intervention to resolve. The data just does not fit into
                  a void*.

                  --
                  Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
                  Available for consulting/temporary embedded and systems.
                  <http://cbfalconer.home .att.net> USE worldnet address!


                  Comment

                  • Arthur J. O'Dwyer

                    #24
                    Re: main function address


                    On Wed, 7 Apr 2004, Leor Zolman wrote:[color=blue]
                    >
                    > Curious -- I've never considered how implicit conversion rules ought to
                    > play out in the arena of variadic functions... on one hand, pointers to
                    > /anything/ implicitly convert to pointer-to-void, but on the other hand
                    > there's no declaration for the receiving pointer-to-void.
                    >
                    > Or, does the implicit conversion apply when the pointer value is extracted
                    > and cast to void * in the receiving function?[/color]

                    I don't understand what you mean. Pointer-to-foo and pointer-to-void
                    can be implicitly "inter-converted" like this:

                    foo *pf;
                    void *pv;

                    pf = pv; pv = pf;

                    Likewise, 'pf' passed to a function prototyped as expecting a void
                    pointer will be implicitly converted. And vice versa.
                    Variadic functions are by definition not prototyped as expecting
                    anything in particular in the "..." part. So when you have

                    printf("foo", pf);

                    the value of 'pf' is passed to 'printf' as a pointer to foo, no
                    matter what the function actually expects. Likewise, in

                    printf("foo", pv);

                    'pv' is passed as a pointer to void.
                    Does that clear up your doubts?

                    HTH,
                    -Arthur

                    Comment

                    • Lukasz Wawrzyniak

                      #25
                      Re: main function address

                      > Undefined behaviour. The standard doesn't define conversions between[color=blue]
                      > function pointers and incomplete or object pointer types. And there is no
                      > guarantee that the type pointer to void is wide enough to be able to
                      > represent the result of such a conversion.
                      >
                      > 6.3.2.3 Pointers
                      >
                      > 1 A pointer to void may be converted to or from a pointer to any
                      > incomplete or object type...
                      > ^^^^^^^^^^^^^^^ ^^^^^^^^^^
                      >
                      > 7 A pointer to an object or incomplete type may be converted to
                      > a pointer to a different object or incomplete type...
                      >
                      > 8 A pointer to a function of one type may be converted to a pointer
                      > to a function of another type and back again; the result shall
                      > compare equal to the original pointer...
                      >
                      > Dan[/color]

                      Can a pointer to a function be converted to an integer type such as
                      size_t such that one could use printf("0x%x\n" , (size_t)main); ?

                      Hmmm, now that I think of it, is it legal (according to the standard)
                      to convert between pointer and integer types at all?

                      Comment

                      • Old Wolf

                        #26
                        Re: main function address

                        Dan.Pop@cern.ch (Dan Pop) wrote[color=blue]
                        > (Old Wolf) writes:[color=green]
                        > >Dan.Pop@cern.c h (Dan Pop) wrote:[color=darkred]
                        > >>
                        > >> The easy way out for printf would be something like %q which expects a
                        > >> pointer to a void function taking no arguments. However, given that %p
                        > >> itself is virtually never used in real world programs, and that
                        > >> %lx or %llx do work on the pointer converted to the appropriate integer
                        > >> type, there is little point on adding %q.[/color]
                        > >
                        > >%p is indispensable[*] on systems without flat address space[/color]
                        >
                        > Have I ever advocating dropping %p from the standard? If not, what
                        > exactly is your point?[/color]

                        I mistook your "%lx works" to mean "%lx works for object pointers"
                        when in fact you meant "%lx works for function pointers". If you had meant
                        what I mistook, then the conclusion "there is little point adding %q"
                        would not have followed, which is what I was getting at.
                        [color=blue]
                        > You got it wrong: using %p for function pointers *is* relying on undefined
                        > behaviour, using %lx for function pointers converted to unsigned long is
                        > NOT undefined behaviour (such conversions are *explicitly* allowed by the
                        > standard).[/color]

                        Right. I was mistakenly talking about object pointers (see above)

                        Comment

                        • Leor Zolman

                          #27
                          Re: main function address

                          On Wed, 7 Apr 2004 16:04:10 -0400 (EDT), "Arthur J. O'Dwyer"
                          <ajo@nospam.and rew.cmu.edu> wrote:
                          [color=blue]
                          >
                          >On Wed, 7 Apr 2004, Leor Zolman wrote:[color=green]
                          >>
                          >> Curious -- I've never considered how implicit conversion rules ought to
                          >> play out in the arena of variadic functions... on one hand, pointers to
                          >> /anything/ implicitly convert to pointer-to-void, but on the other hand
                          >> there's no declaration for the receiving pointer-to-void.
                          >>
                          >> Or, does the implicit conversion apply when the pointer value is extracted
                          >> and cast to void * in the receiving function?[/color]
                          >
                          > I don't understand what you mean. Pointer-to-foo and pointer-to-void
                          >can be implicitly "inter-converted" like this:
                          >
                          > foo *pf;
                          > void *pv;
                          >
                          > pf = pv; pv = pf;
                          >[/color]
                          Yes, of course.
                          [color=blue]
                          >Likewise, 'pf' passed to a function prototyped as expecting a void
                          >pointer will be implicitly converted. And vice versa.[/color]

                          No questions there.
                          [color=blue]
                          > Variadic functions are by definition not prototyped as expecting
                          >anything in particular in the "..." part. So when you have
                          >
                          > printf("foo", pf);
                          >
                          >the value of 'pf' is passed to 'printf' as a pointer to foo, no
                          >matter what the function actually expects.[/color]

                          And therein lies my question. If pf has type pointer-to-foo, but is printed
                          using a %p format conversion, that represents a foo* -> void* conversion
                          without the compiler's "knowledge" ... when the internals of printf extract
                          that argument, it will at some point be "converted" into a void *, but
                          without any knowledge of what it was "before". So is such an implicit
                          conversion officially permitted? I've been writing code that does that
                          forever, and it makes me wonder...

                          Lew pointed out 7.19.6.1, where it says "the argument [to %p] shall be a
                          pointer to void. Pete above points out how (explicit) conversion of a
                          pointer-to-function into a pointer-to-void is a "common extension" (so it
                          is definitely bad karma to omit the cast with a pointer-to-function)...but
                          what is the Standard's take on performing no cast whatsoever on a
                          pointer-to-something-/else/ (not a function, and not void)? IOW, is:
                          int i, *pi = &i;
                          printf("%p\n", pi);
                          conformant?
                          [color=blue]
                          > Likewise, in
                          >
                          > printf("foo", pv);
                          >
                          >'pv' is passed as a pointer to void.[/color]

                          This is the case that seems well-defined to me, in the case of a %p
                          conversion.
                          [color=blue]
                          > Does that clear up your doubts?[/color]

                          Does that clear up my question? :-)

                          I'm quite a newbie at Standard-reading, my implementation experience
                          limited to a very crude subset of pre-C89 C. So please view my questions as
                          /questions/, rather than any deliberate attempt to suggest a problem with
                          the Standard. If I do happen to stumble across any problems (and I guess I
                          may have come close on one or two occasions, even if they weren't
                          original), that's purely by accident.
                          -leor
                          [color=blue]
                          >
                          >HTH,
                          >-Arthur[/color]

                          --
                          Leor Zolman --- BD Software --- www.bdsoft.com
                          On-Site Training in C/C++, Java, Perl and Unix
                          C++ users: Download BD Software's free STL Error Message Decryptor at:
                          An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

                          Comment

                          • Alberto Giménez

                            #28
                            [OT] Re: main function address

                            -----BEGIN PGP SIGNED MESSAGE-----
                            Hash: SHA1

                            El Wed, 07 Apr 2004 10:07:15 +0200, Martin Dickopp escribió:[color=blue]
                            >
                            > Is the cast to `void *' valid? I cannot find anything in the standard
                            > which allows a pointer to a function to be converted to type `void *'.[/color]

                            Hi, I'm new to this group, just a couple of days reading. I can see you
                            are constantly referring to the "Standard" and I've seen in the FAQ that
                            you must pay for it ($18 electronic document).

                            All of you have payed for it? shouldn't a "standard" be free?

                            Thanks in advance and sorry for my english
                            - --
                            Alberto Giménez, SimManiac en el IRC

                            GNU/Linux Debian Woody 3.0 GnuPG ID: 0x3BAABDE1
                            Linux registered user #290801
                            WinError 01E: Timing error - Please wait. And wait. And wait. And wait.
                            -----BEGIN PGP SIGNATURE-----
                            Version: GnuPG v1.0.6 (GNU/Linux)
                            Comment: For info see http://www.gnupg.org

                            iD8DBQFAdHAp0ke CtzuqveERAuOuAJ 0cl6hlfaq+ikGVV KTthj/DUgaJVwCaAiRb
                            4mdlpHHPze7fArd yUEuEe5U=
                            =uj/E
                            -----END PGP SIGNATURE-----

                            Comment

                            • Leor Zolman

                              #29
                              Re: [OT] Re: main function address

                              On Wed, 7 Apr 2004 23:18:33 +0200, Alberto Giménez <algibe@telelin e.es>
                              wrote:
                              [color=blue]
                              >-----BEGIN PGP SIGNED MESSAGE-----
                              >Hash: SHA1
                              >
                              >El Wed, 07 Apr 2004 10:07:15 +0200, Martin Dickopp escribió:[color=green]
                              >>
                              >> Is the cast to `void *' valid? I cannot find anything in the standard
                              >> which allows a pointer to a function to be converted to type `void *'.[/color]
                              >
                              >Hi, I'm new to this group, just a couple of days reading. I can see you
                              >are constantly referring to the "Standard" and I've seen in the FAQ that
                              >you must pay for it ($18 electronic document).
                              >
                              >All of you have payed for it? shouldn't a "standard" be free?[/color]

                              I tried using the free version of the "Draft" Standard that's floating
                              around, and which I guess is legitimately downloadable (although I couldn't
                              find it last time I looked) for free. But there are enough differences that
                              I soon (happily) forked over the $18 for my electronic copy of the Real
                              McCoy.

                              Compared to what the committee members had to pay in order to cover their
                              own expenses just to be on the Standard committee, we're getting a bargain
                              ;-)
                              -leor
                              [color=blue]
                              >
                              >Thanks in advance and sorry for my english[/color]

                              --
                              Leor Zolman --- BD Software --- www.bdsoft.com
                              On-Site Training in C/C++, Java, Perl and Unix
                              C++ users: Download BD Software's free STL Error Message Decryptor at:
                              An STL Error Decryptor for C++ by Leor Zolman of BD Software - available to download here

                              Comment

                              • Arthur J. O'Dwyer

                                #30
                                Pointer args to variadic fxns, was re: main function address


                                On Wed, 7 Apr 2004, Leor Zolman wrote:[color=blue]
                                >
                                > Arthur O'Dwyer <ajo@nospam.and rew.cmu.edu> wrote:[color=green]
                                > > Variadic functions are by definition not prototyped as expecting
                                > > anything in particular in the "..." part. So when you have
                                > >
                                > > printf("foo", pf);
                                > >
                                > > the value of 'pf' is passed to 'printf' as a pointer to foo, no
                                > > matter what the function actually expects.[/color]
                                >
                                > And therein lies my question. If pf has type pointer-to-foo, but is printed
                                > using a %p format conversion, that represents a foo* -> void* conversion
                                > without the compiler's "knowledge" ... when the internals of printf extract
                                > that argument, it will at some point be "converted" into a void *, but
                                > without any knowledge of what it was "before". So is such an implicit
                                > conversion officially permitted? I've been writing code that does that
                                > forever, and it makes me wonder...[/color]

                                If you pass a value of type T to a variadic function, and that function
                                is expecting a value of type U instead, then you have undefined behavior,
                                unless <some legalese involving cv-qualification>. It's not terribly
                                unintuitive, is it?


                                [I think N869 section 7.15.1.1 is wrong when it uses the word
                                "compatible " to describe what I think is really "having the same
                                alignment and size restrictions" or something like that. Unless
                                it was the Committee's intent to have all implementations pass
                                pointers into variadic functions *as void pointers*, and have an
                                implicit conversion take place inside 'va_arg'. Experts, please?]


                                All the exceptions I'm aware of are covered by N869 section 6.2.5.27,
                                which allows things like

                                struct foo p;
                                my_vfunc("actua lly retrieves a struct bar", &p);


                                unsigned char *p = <something>;
                                printf("%p", p);

                                Since 'unsigned char *' and 'void *' are guaranteed to have the same
                                representation (at least, according to my interpretation of the Standard;
                                I know some people think *all* character types are similar to 'void *',
                                and others think that only *at least one* character type is similar
                                to 'void *'), this is conforming code.
                                But it's so easy to add the cast every time and make sure, that it's
                                just not worth fiddling around with special cases. :)
                                [color=blue]
                                > Lew pointed out 7.19.6.1, where it says "the argument [to %p] shall be a
                                > pointer to void. Pete above points out how (explicit) conversion of a
                                > pointer-to-function into a pointer-to-void is a "common extension" (so it
                                > is definitely bad karma to omit the cast with a pointer-to-function)...but
                                > what is the Standard's take on performing no cast whatsoever on a
                                > pointer-to-something-/else/ (not a function, and not void)? IOW, is:
                                > int i, *pi = &i;
                                > printf("%p\n", pi);
                                > conform[ing]?[/color]

                                No. See above; 'int *' and 'void *' do not necessarily have the
                                same representation or alignment requirements.

                                -Arthur

                                Comment

                                Working...