overriding standard functions

S

Szabolcs Nagy

i'm writing because i wonder about the semantics of overridden
standard functions

i imagined that when i compiled a c code then a linker would link my
code against a libc so there would be errors about multiple
definitions of overridden standard functions, however

#include <stdio.h>

int fclose(FILE *f) {
puts("overridden fclose");
return 0;
}

int main(void) {
return fclose(stdout);
}

compiles cleanly with the compiler implementations i've tried

does the standard allow this?

what should happen if i compile (and link) this code together with
other code that uses fclose()? (i guess fclose should not be
implemented by a macro in the standard lib so the overridden fclose
would be used there)
 
K

krishan

i'm writing because i wonder about the semantics of overridden
standard functions

i imagined that when i compiled a c code then a linker would link my
code against a libc so there would be errors about multiple
definitions of overridden standard functions, however

#include <stdio.h>

int fclose(FILE *f) {
    puts("overridden fclose");
    return 0;

}

int main(void) {
    return fclose(stdout);

}

compiles cleanly with the compiler implementations i've tried

does the standard allow this?

what should happen if i compile (and link) this code together with
other code that uses fclose()? (i guess fclose should not be
implemented by a macro in the standard lib so the overridden fclose
would be used there)

Why are you doing this? you can use LD_PRELOAD if you want to do this.
 
J

James Kuyper

Szabolcs said:
i'm writing because i wonder about the semantics of overridden
standard functions

i imagined that when i compiled a c code then a linker would link my
code against a libc so there would be errors about multiple
definitions of overridden standard functions, however

#include <stdio.h>

int fclose(FILE *f) {
puts("overridden fclose");
return 0;
}

int main(void) {
return fclose(stdout);
}

compiles cleanly with the compiler implementations i've tried

does the standard allow this?

The standard says that this is undefined behavior; a phrase that gives
implementations enough freedom to either allow it, disallow it, or have
it malfunction, among an infinity variety of more complicated options. I
know that there are systems which do allow it, and ones that don't - I'm
not sure how many of the other more complicated possibilities are
actually implemented.
 
B

Barry Schwarz

i'm writing because i wonder about the semantics of overridden
standard functions

i imagined that when i compiled a c code then a linker would link my
code against a libc so there would be errors about multiple
definitions of overridden standard functions, however

#include <stdio.h>

int fclose(FILE *f) {
puts("overridden fclose");
return 0;
}

int main(void) {
return fclose(stdout);
}

compiles cleanly with the compiler implementations i've tried

does the standard allow this?

what should happen if i compile (and link) this code together with
other code that uses fclose()? (i guess fclose should not be
implemented by a macro in the standard lib so the overridden fclose
would be used there)

As others have noted, you have gone beyond the standard and if you
need a definitive answer for a particular implementation, you need to
ask in a group where experts on that implementation live.

On all the systems I have worked on (a statistically insignificantly
small sample so take with a grain of salt), the linkers have always
used "for an external reference that requires definition, use the
first definition encountered in the specified search order" rule.

In your example, since your object file is obviously first, it
would use one you defined and ignore any other definition of fclose
that it found (e.g., while looking for the definition of puts).

If you had split the two functions into separate source files
and somehow directed the linker to search main, system, and fclose
object files in that order, then it would have used the system
function and ignored yours.

However, if an object file defines multiple external entities, when
that object file is included, all the entities become known to the
linker. If two such entities in different included object files have
the same name, that is when the linker complains about duplication.
For example:

main.c
int mine = 5;
void func2(void); /*prototype*/
void func1(void){...}
int main(void){
...
func1();
...
func2();
...}

func2.c
int mine = 10;
void func1(void){...}
void func2(void){...}

In the process of resolving references from main.c's object file, it
must include func2.c's object file. At that point it should complain
about mine and func1 both being multiply defined.
 
K

Keith Thompson

Joe Wright said:
Nothing to do with C really. If a definition of fclose() exists in the
.c file then it is 'resolved' there and we never ask the linker to
find it for us.

Nevertheless, the behavior is undefined, and the implementation may
legally do anything it likes with the call, including calling the
user-defined function, calling the library function, or anything
else.

For the code shown, if <stdio.h> defines fclose() as a function-like
macro, then the function declaration is almost certainly a syntax
error. You can avoid that particular problem with "#undef fclose",
but the behavior is still undefined.
 
N

Nobody

i'm writing because i wonder about the semantics of overridden
standard functions
what should happen if i compile (and link) this code together with
other code that uses fclose()?

This is extremely implementation-specific. If it doesn't simply result
in an error, your program may use either your version or libc's
version, libc may use either your version or libc's version, and other
libraries may use either your version or libc's version. Most of the
combinations are possible (although your program using libc's version
while everything else uses your version is pretty unlikely).

If you only want your program (and not third-party libraries) to use your
version, give your function a different name and define e.g. fclose as a
macro.

If you want to force libraries to use your version, you'll need to
read the documentation for your linker, loader, and the platform's
executable format (ELF, COFF etc).
 

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,774
Messages
2,569,599
Members
45,175
Latest member
Vinay Kumar_ Nevatia
Top