Pointers to standard library functions

F

Francine.Neary

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.)
 
I

Ian Collins

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

Ian Collins

Ian said:
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.
 
F

Francine.Neary

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?
 
A

Army1987

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.
 
E

Eric Sosman

Ian said:
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.
 
D

Dave Vandervies

<[email protected]> ha scritto nel messaggio


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
 
K

Keith Thompson

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.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top