By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
455,903 Members | 1,090 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 455,903 IT Pros & Developers. It's quick & easy.

Pointers to standard library functions

P: n/a
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 '07 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Fr************@googlemail.com 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.
May 26 '07 #2

P: n/a
Ian Collins wrote:
Fr************@googlemail.com 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.
May 26 '07 #3

P: n/a
On May 26, 11:37 am, Ian Collins <ian-n...@hotmail.comwrote:
Ian Collins wrote:
Francine.Ne...@googlemail.com 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 '07 #4

P: n/a

<Fr************@googlemail.comha scritto nel messaggio
news:11**********************@u30g2000hsc.googlegr oups.com...
On May 26, 11:37 am, Ian Collins <ian-n...@hotmail.comwrote:
>Ian Collins wrote:
Francine.Ne...@googlemail.com 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.
May 26 '07 #5

P: n/a
Ian Collins wrote:
Fr************@googlemail.com 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
es*****@acm-dot-org.invalid
May 26 '07 #6

P: n/a
In article <f3*********@tdi.cu.mi.it>, Army1987 <pl********@for.itwrote:
>
<Fr************@googlemail.comha scritto nel messaggio
news:11**********************@u30g2000hsc.googleg roups.com...
>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 dj******@csclub.uwaterloo.ca
Well, it's logically consistent and interesting. That appears to be
all mathematicians need.
--James Riden in the scary devil monastery
May 26 '07 #7

P: n/a
dj******@caffeine.csclub.uwaterloo.ca (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) ks***@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."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
May 26 '07 #8

This discussion thread is closed

Replies have been disabled for this discussion.