|
|
 |
 |
 |
 |
Pointers to standard library functions
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.)
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. -- Ian Collins.
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. -- Ian Collins.
On May 26, 11:37 am, Ian Collins <ian-n@hotmail.com> wrote:
> 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.
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. >> [... 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 esos@acm-dot-org.invalid
In article <f3972i$t @tdi.cu.mi.it>, Army1987 <please. @for.it> wrote: ><Francine.Ne@googlemail.com> ha scritto nel messaggio >news:1180179981.394918.235050@u30g2000hsc.googlegroups.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 dj3va@csclub.uwaterloo.ca Well, it's logically consistent and interesting. That appears to be all mathematicians need. --James Riden in the scary devil monastery
dj3va @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) k@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"
|
 |
 |
 |
 |
|