calling my custom function same as library function

D

Deniz Bahar

Hi,

I would like to call one of my functions the exact name as an existing
C library function (for example K&R2 exercises asks me to make an atof
function). If I don't include the header with the declaration for the
C library function (stdlib.h in this case) then define/declare my own
function with the same name, am I safe? It seems to work on my
compiler, but I wonder if this is portable or even acceptable? thx
 
K

Kenny McCormack

Hi,

I would like to call one of my functions the exact name as an existing
C library function (for example K&R2 exercises asks me to make an atof
function). If I don't include the header with the declaration for the
C library function (stdlib.h in this case) then define/declare my own
function with the same name, am I safe? It seems to work on my
compiler, but I wonder if this is portable or even acceptable? thx

Yes, but you can't talk about it here.
 
W

Walter Roberson

:I would like to call one of my functions the exact name as an existing
:C library function (for example K&R2 exercises asks me to make an atof
:function). If I don't include the header with the declaration for the
:C library function (stdlib.h in this case) then define/declare my own
:function with the same name, am I safe?

Library function names are not 'reserved'.

If your function has the same prototype as the existing one, then
there is no problem including the header file. The standard
header files only give the linkage information for the cases where
you -do- use the library function: the header files do not in
any way "bring in" the library functions. When you use the library
functions, it is the linker that puts them into the program address
space, not the header files.

:It seems to work on my
:compiler, but I wonder if this is portable or even acceptable? thx

It is portable to any system I have ever heard of, and it is
often used. It is a fundamental mechanism by which functionality
can be extended, such as for replacing the malloc() function with
one that is more efficient or which provides debugging hooks.

Exact linker details differ, but the general practice is that
the code for the standard C library functions is stored in an
object "library", and that the linker will only pull in references
to those library functions for which it has unsatisfied references.
When you provide your own version of a library function, then code
that calls upon that function will find your definition of that
name and will use that: there will not be any unsatisfied references
to the name and so the linker will not try to reference the library
routine by that name.


There are two major competing linkage paradigms:

- In one of them, the order that the files are named is unimportant: the
linker examines all the user-provided object files, finds all the
definitions and unsatisfied references to routines, and to the greatest
extent possible uses the definitions from -any- of the given object
files. The linker then only pulls in those library routines which
there is a reference to but which were not defined by the user.
This paradigm requires at least two passes over the object files,
once to find out what all is defined in any user-provided file, and the
second time to do the linking.

- In the second linker paradigm, the order of the files is important.
The linker proceeds from left [first on the line] towards the right
[last on the line], accumulating definitions and unsatisfied
references as it goes. At any point, when there is an unsatisfied
reference to a function and a definition of that function is seen,
the definition is used to satisfy the reference. That definition
may reference other functions; if those other functions are defined
in the same object then that definition is used but otherwise a new
unsatisfied reference is created that must be filled by something
further to the right. For such linkers, there is no record kept
of definitions which have -already- been seen: if the first
file defines FOO and the second file calls upon FOO, then the
linker will -not- go back to the first file to find FOO: it will
expect -another- FOO to be defined in a later object. This kind
of linkage is "one pass": it never needs to go back to an existing
file, and never needs to keep track of which file defines which
object [only of which unsatisfied references there are.]


I have not used the first paradigm very much, so I am not sure
how it handles multiple definitions. In the second paradigm, if
you want to define something that pre-empts a library routine,
all you have to do is put its definition further right on the
command line than anything that calls upon that function:
as the linker passes from left to right, it will see your atof()
or whatever and will use that to satisfy any calls to atof()
that were further left; with there no longer being any unsatisfied
calls to atof(), the library object copy of the routine will not
be needed.

There are some other tricks to linkers as well, but they tend
to be more implimentation-dependant. One-pass linkers are fairly
common, but you should read the manual pages for the linker you
are using so that you know how it processes definitions.
Redefining a library function is not exceptional for utility
packages, and there is almost always -some- way to do it.
 
J

Jack Klein

Hi,

I would like to call one of my functions the exact name as an existing
C library function (for example K&R2 exercises asks me to make an atof
function). If I don't include the header with the declaration for the
C library function (stdlib.h in this case) then define/declare my own
function with the same name, am I safe? It seems to work on my
compiler, but I wonder if this is portable or even acceptable? thx

According to the C standard, it is neither portable nor acceptable to
use the name of a library function in a context where it has external
linkage.

That means, you can define a function named "atof" if and only if you
define it with the static keyword, which means you can only call it by
name from within the same source file.

Otherwise you generate undefined behavior.
 
J

Jack Klein

:I would like to call one of my functions the exact name as an existing
:C library function (for example K&R2 exercises asks me to make an atof
:function). If I don't include the header with the declaration for the
:C library function (stdlib.h in this case) then define/declare my own
:function with the same name, am I safe?

Library function names are not 'reserved'.

The C standard disagrees:

"7.1.3 Reserved identifiers
1 Each header declares or defines all identifiers listed in its
associated subclause, and optionally declares or defines identifiers
listed in its associated future library directions subclause and
identifiers which are always reserved either for any use or for use as
file scope identifiers."

....and then, in the itemized list that is also part of paragraph 1:

"All identifiers with external linkage in any of the following
subclauses (including the future library directions) are always
reserved for use as identifiers with external linkage."

....therefore, it is undefined to define your own function with the
same name as any standard library function, unless you use the static
keyword to limit it to internal linkage.

Whether or not this particular instance of undefined behavior "works"
is in the eye of the beholder, since the C standard requireth not.
 
W

Walter Roberson

:According to the C standard, it is neither portable nor acceptable to
:use the name of a library function in a context where it has external
:linkage.

That does not sound right. Every library function has external linkage
relative to the user code.
 
G

Gordon Burditt

I would like to call one of my functions the exact name as an existing
C library function (for example K&R2 exercises asks me to make an atof
function). If I don't include the header with the declaration for the
C library function (stdlib.h in this case) then define/declare my own
function with the same name, am I safe?
No.

It seems to work on my
compiler, but I wonder if this is portable or even acceptable? thx

The problem you typically run into (if there are problems) is that
when you get something out of the library, you get X, Y, and Z
together (not separately), and if you have a replacement X and also
need Y (directly or indirectly), you end up with two different
copies of X loaded and a "multiply defined symbol" error.

Another problem that may come up is that your replacement for X is
also called from library functions, and either your interface for
X is (intentionally) not the same, or your interface for X does not
implement some magic undocumented stuff used internally by the
library.

Gordon L. Burditt
 
C

Chris Torek

Library function names are not 'reserved'.

This is not quite right.

Library function names are reserved for use as external-linkage
identifiers. Hence the following source-file-fragment is valid,
guaranteed C code:

#include <stdio.h>
/* do not include <math.h> */

static int sin(void) {
puts("let he who is without sin() cast the first stone");
}

/* code that calls sin() */

but this one is not:

#include <stdio.h>
/* again, do not include <math.h> */

int tan(void) {
puts("sit in the sun for a few minutes for a nice tan()");
}

/* code that calls tan() */

Among other problems with attempting to override a library function
is the fact that modern C compilers may not actually *call* anything
where you put in a library-function call. For instance, this code:

/* #include <string.h> -- deliberately commented out */
#include <stdlib.h> /* for size_t */

void *memcpy(void *, const void *, size_t);

void f(int *p) {
memcpy(p, "123", 4);
}

produces the following x86 assembly code when run through GCC:

.p2align 2,,3
.globl f
.type f,@function
f:
movl $3355185, (%eax)
ret

(The function f() consists entirely of two instructions, neither
one a call to memcpy(). Compile with "-O -fomit-frame-pointer
-mregparm=3" to obtain this code. Otherwise you will get a little
extra code to deal with stack frames and/or parameter passing.)

(If you make the memcpy() declaration "static", gcc will emit a
call to the [missing] function, as required for Standard C. Of
course, you then have to define your static [internal-linkage]
memcpy() as well.)

(Even if you get a call to a function where you used a Standard C
Library function call, there is no guarantee that the call will be
made in the "usual fashion", or to the name you wrote. But this
tends to be less common than inline expansion of the "known"
function, since the latter has a greater return-on-investment in
most cases.)
 
E

Eric Sosman

Walter said:
:I would like to call one of my functions the exact name as an existing
:C library function (for example K&R2 exercises asks me to make an atof
:function). If I don't include the header with the declaration for the
:C library function (stdlib.h in this case) then define/declare my own
:function with the same name, am I safe?

Library function names are not 'reserved'.

That will come as a surprise to the authors of
Section 7.1.3, paragraph 1, fourth point:

"All identifiers with external linkage in any
of the following subclauses (including the future
library directions) are always reserved for use
as identifiers with external linkage."
> [stuff about the way many linkers work]

Even if the linker is able to substitute a user-written
function for an actual library function, there is no guarantee
the program will work. Library functions may have private,
unpublished interfaces with each other, "back doors" into each
others' operations. In some cases this seems the only way to
implement the function: for example, fflush(NULL) needs some
way to find the eligible streams, free() needs a way to tell
malloc() that the memory has become available again, exit()
needs to find all the functions registered with atexit(),
and so on. The nature and number of such interrelationships
varies from one C implementation to the next, and there is no
requirement that they be documented.

As a practical matter it is quite likely that replacing
atof() will work (even though it may well be connected with
strtod() and the *scanf() family in arcane ways). However,
the Standard does not promise it will work -- the Standard,
in fact, forbids the attempt -- and if the program misbehaves
you have no one to blame but yourself.
 
W

Walter Roberson

|On 28 Feb 2005 02:48:17 GMT, (e-mail address removed)-cnrc.gc.ca (Walter
|Roberson) wrote in comp.lang.c:

|> Library function names are not 'reserved'.

|The C standard disagrees:

|"7.1.3 Reserved identifiers
|1 Each header declares or defines all identifiers listed in its
|associated subclause, and optionally declares or defines identifiers
|listed in its associated future library directions subclause and
|identifiers which are always reserved either for any use or for use as
|file scope identifiers."

The 'and identifiers which are always reserved' is distinct in that
sentance from the declarations listed and the future directions list.
That sentance does *not* say that the identifiers in headers are
reserved: it says that one of the things that might be in a header
file is a declaration or definition of an identifier that is always
reserved. The part of the sentance about "for any use" is
in contrast to "as file scope identifiers": header files might
contain declarations or definitions for one or both types, or neither.


:...and then, in the itemized list that is also part of paragraph 1:

:"All identifiers with external linkage in any of the following
:subclauses (including the future library directions) are always
:reserved for use as identifiers with external linkage."

Reserving an identifier for external linkage does not reserve it
for implimentation library definition.

:...therefore, it is undefined to define your own function with the
:same name as any standard library function, unless you use the static
:keyword to limit it to internal linkage.

No, the part about being reserved for external linkage that you
quote would preclude using the identifier with internal linkage.


:Whether or not this particular instance of undefined behavior "works"
:is in the eye of the beholder, since the C standard requireth not.

The C standard is, of course, not about to say that if you
define a function with the same name as a library function that
somehow you are going to magically get the library function
behaviour even though your own code would be called. The C standard
cannot make any promises about what is going to happen if you
define your own version of a function -- not because such a thing
is prohibitted, but simply because the C standardization committee
can't know what your version of the routine is going to do.


The OP suggested that he might omit the header file. Any "reserved"
behaviour that you are imputing by way of the initial part of paragraph
1 of 7.1.3 would then be irrelevant. (And I don't agree that
that portion reserves any behaviour.)
 
W

Walter Roberson

: Even if the linker is able to substitute a user-written
:function for an actual library function, there is no guarantee
:the program will work. Library functions may have private,
:unpublished interfaces with each other, "back doors" into each
:eek:thers' operations.

That is a good point, which is of concern with "global" linkers
that examine all the files first before choosing which function
to link to. It turns out, though, not to be a problem with
one-pass linkers unless the user explicitly names the relevant
libraries before they name their object file [and even then,
it turns out not to be a problem for the standard library.]

In one pass linkers, if the user's object file defining [say]
malloc() is placed between their other object files and the
[possibly implicit] reference to the standard C library, then
the user's definition will satisfy any malloc() references in
the user's code; the one-pass linker will then "forget" that it
has seen a definition of malloc() and will proceed onwards. When
it then encounters an unsatisfied reference to malloc() inside the
standard libraries, then it will either satisify the reference from
the same library or will look further right for the definition,
just as would normally be the case. That is, absent deliberate
manipulation to cause otherwise, user definitions of library
functions will [for one pass linkers] apply only to the user
code, and the library definition will apply for anything further
right such as the other libraries. One-pass linkers do not
do "global" replacement of function references: only
unsatisfied references to the left of the current object.

I can't speak on what happens in practice with multipass linkers.
I would, though, point out that it would be unusual for
private interfaces to exist in library functions except at file
scope, which would use internal linkage rather than external.
 
D

DHOLLINGSWORTH2

Kenny McCormack said:
Yes, but you can't talk about it here.
He's right this is the You cant do that group. You want the Yes no problem
group.

comp.lang.c++

Dan
 
J

Jack Klein

: Even if the linker is able to substitute a user-written
:function for an actual library function, there is no guarantee
:the program will work. Library functions may have private,
:unpublished interfaces with each other, "back doors" into each
:eek:thers' operations.

That is a good point, which is of concern with "global" linkers

[snip a lot of off-topic speculation about linkers]

Linkers are completely off-topic here. They do not exist. They are
not defined by the C standard, which only requires that an
implementation provide some method of building a program from separate
translation units. The details of how an implementation does so is
not defined by the standard and so is off-topic here.

You seem to deliberately refuse to get the point. At least two
others, besides myself, have quoted the relevant section of the C
standard that states that the names of library functions are reserved
with external linkage. If you misuse a reserved identifier, the C
standard does not define the result. That is undefined behavior, and
once a program invokes undefined behavior, the results are off-topic
here.

If you want to have a grand discussion of linkers, I suggest you try
the moderated group
 
W

Walter Roberson

:Linkers are completely off-topic here.

Let me save you some trouble:

I will be posting on matters which are widely considered "off-topic".
If you don't want to read those messages, feel free to killfile me.

I have noticed that some people in this newsgroup (I don't particularily
recall you being one of them) react to questions they consider to be
"off-topic" with what I can only term rudeness. I can't do anything about
those people, but I can instead choose to provide answers that are a bit
more useful. Some people have essentially said "If you don't like the way
answers are given here, feel free to give your own answers" -- so I am.

comp.lang.c did not start out as a "Don't talk about anything outside
the standard" newsgroup: it has become such a newsgroup because people
have allowed it to become that way. It isn't going to get back to it's
original purpose by people blithely accepting the status quo of
deliberate refusal to help on matters outside the standard.

Discussion of C compilers is within the closest thing this newsgroup
has to a charter, namely the statement of purpose of the news.* group
that got renamed to comp.lang.c .

If people want to killfile me for honestly trying to help people, then
I can live with that. One must live with one's conscience; to
be able to help someone but to refuse to is not something I can easily
contenence.
 
F

Flash Gordon

Walter said:
:Linkers are completely off-topic here.

Let me save you some trouble:

I will be posting on matters which are widely considered "off-topic".
If you don't want to read those messages, feel free to killfile me.

If everyone killfiles you then they won't be able to correct the
misinformation you provide, such as saying that you can override the
library functions when this is not necessarily the case and it is
definitely not portable.
I have noticed that some people in this newsgroup (I don't particularily
recall you being one of them) react to questions they consider to be
"off-topic" with what I can only term rudeness.

The original question was *not* off topic. The question was "is this
portable and safe?" to which the ON TOPIC answer is no and this was
stated politely.

You were even corrected politely after your initial incorrect assertion
that it was no problem.

If people want to killfile me for honestly trying to help people, then
I can live with that. One must live with one's conscience; to
be able to help someone but to refuse to is not something I can easily
contenence.

The initial problem here is that your answer to an ON TOPIC question was
inaccurate. After further discussion about what the standard means you
are allowed to do (which I would consider potentially reasonable even
though I consider your opinion to be wrong) you then went on to how you
believe linkers work which is generally considered OFF TOPIC as a
justification as to why you were right. Jack pointed out that the linker
details are off topic and that more than one person has quoted the
parts of the standard that say you are wrong.
 
K

Kenny McCormack

The C standard disagrees:

"7.1.3 Reserved identifiers
1 Each header declares or defines all identifiers listed in its
associated subclause, and optionally declares or defines identifiers
listed in its associated future library directions subclause and
identifiers which are always reserved either for any use or for use as
file scope identifiers."

...and then, in the itemized list that is also part of paragraph 1:

"All identifiers with external linkage in any of the following
subclauses (including the future library directions) are always
reserved for use as identifiers with external linkage."

...therefore, it is undefined ...

blah, blah, blah
blah, blah, blah
blah, blah, blah

I.e., as I said originally: Yes, you can do it and everybody does it.

But you can't talk about it here!
 
K

Kenny McCormack

Flash Gordon said:
The initial problem here is that your answer to an ON TOPIC question was
inaccurate. After further discussion about what the standard means you are
allowed to do (which I would consider potentially reasonable even though
I consider your opinion to be wrong) you then went on to how you believe
linkers work which is generally considered OFF TOPIC as a justification as
to why you were right. Jack pointed out that the linker details are off
topic and that more than one person has quoted the parts of the standard
that say you are wrong.

Just remember: According to the bible, pi = 3.0

So, if I say that it is really 3.14159..., I guess that's inaccurate, and
I should be killfiled, right?
 
R

Richard Tobin

Chris Torek said:
Library function names are reserved for use as external-linkage
identifiers.

I always think this wording is rather confusing. After all, using it
as an external-linkage identifier is exactly what the OP wants to do!

-- Richard
 
I

infobahn

Kenny said:
Just remember: According to the bible, pi = 3.0

It does? The best reference I can find to pi in the Bible is 1 Kings
Chapter 7 verse 23: "Also he made a molten sea of ten cubits from
brim to brim, round in compass, and five cubits the height thereof;
and a line of thirty cubits did compass it round about."

If we assume that "round" is intended to mean "circular" (rather than,
say, elliptical or ovoid), we can deduce pi from this statement, but
only to the limits of accuracy provided. We have no justification for
assuming that any figure is given to an accuracy of better than plus
or minus half a cubit; therefore, the best we can get from this text
is that pi is in the range 2.8095+ to 3.2105+ (and we know from our
independent research that this encompasses the actual value of pi
perfectly adequately).
So, if I say that it is really 3.14159..., I guess that's inaccurate, and
I should be killfiled, right?

No. You should be corrected for making an incorrect deduction,
congratulated on getting six digits of pi right, and berated for
introducing an off-topic discussion (mathematics is not topical
in comp.lang.c). Killfiling is not a good solution to the problem
of people who post incorrect material.
 
K

Kenny McCormack

So, if I say that it is really 3.14159..., I guess that's inaccurate, and
I should be killfiled, right?

No. You should be corrected for making an incorrect deduction,
congratulated on getting six digits of pi right, and berated for
introducing an off-topic discussion (mathematics is not topical
in comp.lang.c). Killfiling is not a good solution to the problem
of people who post incorrect material.[/QUOTE]

You're funny. Keep it up.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top