Pointers to standard library functions

Discussion in 'C Programming' started by Francine.Neary@googlemail.com, May 26, 2007.

  1. Guest

    This may well be implementation-defined or undefined behavior... if
    so, then of course that's a good enough answer.

    Consider the following situation:

    /* file1.c */

    int (*f)(const char *, const char *);

    function1()
    {
    ...
    f=strcmp;
    ...
    }



    /* file2.c */

    extern int (*f)(const char *, const char *);

    /* function1 has definitely been called by now */
    function2()
    {
    /* uses f */
    }

    Is the function2 guaranteed to invoke strcmp? In other words, are
    addresses of standard library functions guaranteed to be constant
    across different files?

    (Obviously what I've presented looks silly - actually what I have is a
    table of function pointers set up in one file that I want to access
    from another, and some of them may be pointers to library functions.
    The above is a simplification illustrating the question.)
     
    , May 26, 2007
    #1
    1. Advertising

  2. Ian Collins Guest

    wrote:
    > This may well be implementation-defined or undefined behavior... if
    > so, then of course that's a good enough answer.
    >
    > Consider the following situation:
    >
    > /* file1.c */
    >
    > int (*f)(const char *, const char *);
    >
    > function1()
    > {
    > ...
    > f=strcmp;
    > ...
    > }
    >
    >
    >
    > /* file2.c */
    >
    > extern int (*f)(const char *, const char *);
    >
    > /* function1 has definitely been called by now */
    > function2()
    > {
    > /* uses f */
    > }
    >
    > Is the function2 guaranteed to invoke strcmp? In other words, are
    > addresses of standard library functions guaranteed to be constant
    > across different files?
    >

    There will only one instance of any function with global scope.

    --
    Ian Collins.
     
    Ian Collins, May 26, 2007
    #2
    1. Advertising

  3. Ian Collins Guest

    Ian Collins wrote:
    > wrote:
    >> This may well be implementation-defined or undefined behavior... if
    >> so, then of course that's a good enough answer.
    >>
    >> Consider the following situation:
    >>
    >> /* file1.c */
    >>
    >> int (*f)(const char *, const char *);
    >>
    >> function1()
    >> {
    >> ...
    >> f=strcmp;
    >> ...
    >> }
    >>
    >>
    >>
    >> /* file2.c */
    >>
    >> extern int (*f)(const char *, const char *);
    >>
    >> /* function1 has definitely been called by now */
    >> function2()
    >> {
    >> /* uses f */
    >> }
    >>
    >> Is the function2 guaranteed to invoke strcmp? In other words, are
    >> addresses of standard library functions guaranteed to be constant
    >> across different files?
    >>

    > There will only one instance of any function with global scope.
    >

    I should have added make sure the standard library functions in question
    are implemented as functions and not as macros.

    --
    Ian Collins.
     
    Ian Collins, May 26, 2007
    #3
  4. Guest

    On May 26, 11:37 am, Ian Collins <> wrote:
    > Ian Collins wrote:
    > > wrote:
    > >> This may well be implementation-defined or undefined behavior... if
    > >> so, then of course that's a good enough answer.

    >
    > >> Consider the following situation:

    >
    > >> /* file1.c */

    >
    > >> int (*f)(const char *, const char *);

    >
    > >> function1()
    > >> {
    > >> ...
    > >> f=strcmp;
    > >> ...
    > >> }

    >
    > >> /* file2.c */

    >
    > >> extern int (*f)(const char *, const char *);

    >
    > >> /* function1 has definitely been called by now */
    > >> function2()
    > >> {
    > >> /* uses f */
    > >> }

    >
    > >> Is the function2 guaranteed to invoke strcmp? In other words, are
    > >> addresses of standard library functions guaranteed to be constant
    > >> across different files?

    >
    > > There will only one instance of any function with global scope.

    >
    > I should have added make sure the standard library functions in question
    > are implemented as functions and not as macros.


    Which standard library functions are allowed to be implemented as
    macros?

    > --
    > Ian Collins.
     
    , May 26, 2007
    #4
  5. Army1987 Guest

    <> ha scritto nel messaggio
    news:...
    > On May 26, 11:37 am, Ian Collins <> wrote:
    >> Ian Collins wrote:
    >> > wrote:
    >> >> This may well be implementation-defined or undefined behavior... if
    >> >> so, then of course that's a good enough answer.

    >>
    >> >> Consider the following situation:

    >>
    >> >> /* file1.c */

    >>
    >> >> int (*f)(const char *, const char *);

    >>
    >> >> function1()
    >> >> {
    >> >> ...
    >> >> f=strcmp;
    >> >> ...
    >> >> }

    >>
    >> >> /* file2.c */

    >>
    >> >> extern int (*f)(const char *, const char *);

    >>
    >> >> /* function1 has definitely been called by now */
    >> >> function2()
    >> >> {
    >> >> /* uses f */
    >> >> }

    >>
    >> >> Is the function2 guaranteed to invoke strcmp? In other words, are
    >> >> addresses of standard library functions guaranteed to be constant
    >> >> across different files?

    >>
    >> > There will only one instance of any function with global scope.

    >>
    >> I should have added make sure the standard library functions in question
    >> are implemented as functions and not as macros.

    >
    > Which standard library functions are allowed to be implemented as
    > macros?


    All of them (if they are, they must evalue each argument exactly
    once, have enough parens, etc., that is the user needn't be aware
    they are macros). The exception is that getc and putc may evalue
    argument several times.
    But there must also be an actual function (except for assert() and few
    others).
    Here it is irrelevant, since the fact that strcmp isn't followed by
    a ( prevents the preprocessor to replace it with the macro, so the
    actual function is used.
     
    Army1987, May 26, 2007
    #5
  6. Eric Sosman Guest

    Ian Collins wrote:
    > wrote:
    >> This may well be implementation-defined or undefined behavior... if
    >> so, then of course that's a good enough answer.
    >>
    >> [... module A aims a function pointer at strcmp, module B
    >> uses the pointer ...]
    >>
    >> Is the function2 guaranteed to invoke strcmp? In other words, are
    >> addresses of standard library functions guaranteed to be constant
    >> across different files?
    >>

    > There will only one instance of any function with global scope.


    How can a program detect the number of "instances" of
    a function? It can, extending Francine Neary's sample, form
    a lot of pointers to a function and then compare them, and
    for Standard library functions I believe they will always
    compare equal (7.1.2p6 says Standard library function names
    have external linkage, and equality should follow).

    But pointer comparisons can only detect the particular
    "instances" that the pointers point to, and can't tell whether
    other "instances" are the same or are separate. That is,
    there might be forty-two copies of strcmp() lying around in a
    program, forty-one of them expanded in-line at the points of
    call and another compiled separately to be a target for all
    those pointer variables. I can't find any explicit permission
    for an implementation to make Standard functions `inline', but
    I can't find a prohibition, either.

    Fifteen or more years ago there was a thread about whether
    the expression `memcpy == memmove' could be true. I recall that
    the debate went on for quite a while, but I don't recall it coming
    to a definitive conclusion.

    At any rate: Francine Neary's function pointer will at the
    very least point to "a" strcmp, even if not to "the" strcmp.

    --
    Eric Sosman
    lid
     
    Eric Sosman, May 26, 2007
    #6
  7. In article <f3972i$t4$>, Army1987 <> wrote:
    >
    ><> ha scritto nel messaggio
    >news:...


    >> Which standard library functions are allowed to be implemented as
    >> macros?

    >
    >All of them (if they are, they must evalue each argument exactly
    >once, have enough parens, etc., that is the user needn't be aware
    >they are macros). The exception is that getc and putc may evalue
    >argument several times.


    In general, any macro masking a standard library function must act exactly
    like the function it's masking, unless the standard specifically says
    otherwise. (I think there's a blanket exemption for lacking sequence
    points that would be in the function call, but verifying that would take
    more than the quick grep of n869 I just made.)
    (The fact that function-like macros don't get expanded unless the name
    of the macro is followed by a '(' makes the "use function name as pointer
    to that function" part of that trivial.)

    >But there must also be an actual function (except for assert() and few
    >others).


    assert isn't a standard library function; it's a macro defined by the
    standard library.


    dave

    --
    Dave Vandervies
    Well, it's logically consistent and interesting. That appears to be
    all mathematicians need.
    --James Riden in the scary devil monastery
     
    Dave Vandervies, May 26, 2007
    #7
  8. (Dave Vandervies) writes:
    [...]
    > In general, any macro masking a standard library function must act exactly
    > like the function it's masking, unless the standard specifically says
    > otherwise. (I think there's a blanket exemption for lacking sequence
    > points that would be in the function call, but verifying that would take
    > more than the quick grep of n869 I just made.)

    [...]

    Correct.

    Quoting n1124 7.1.4p1:

    ...

    Any function declared in a header may be additionally implemented
    as a function-like macro defined in the header, so if a library
    function is declared explicitly when its header is included, one
    of the techniques shown below can be used to ensure the
    declaration is not affected by such a macro.
    ...
    Any invocation of a library function that is implemented as a
    macro shall expand to code that evaluates each of its arguments
    exactly once, fully protected by parentheses where necessary, so
    it is generally safe to use arbitrary expressions as arguments.

    with a footnote:

    Such macros might not contain the sequence points that the
    corresponding function calls do.

    One interesting consequence is that the expression sin(x) + cos(x) may
    invoke undefined behavior, since both sin and cos can modify errno
    without an intervening sequence point.

    --
    Keith Thompson (The_Other_Keith) <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."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 26, 2007
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Marc Thrun
    Replies:
    15
    Views:
    884
    Tim Rentsch
    Oct 4, 2005
  2. newbie

    Pointers to char pointers in functions

    newbie, Sep 18, 2006, in forum: C Programming
    Replies:
    9
    Views:
    327
    August Karlstrom
    Sep 24, 2006
  3. Replies:
    5
    Views:
    885
  4. cerr

    pointers, pointers, pointers...

    cerr, Apr 7, 2011, in forum: C Programming
    Replies:
    12
    Views:
    733
  5. ajaybgr
    Replies:
    18
    Views:
    1,086
    Philip Lantz
    Sep 7, 2012
Loading...

Share This Page