On Sun, 16 Jan 2011 08:30:01 -0500, Eric Sosman
On 1/16/2011 3:59 AM, Richard Sanders wrote:
Here is the compiling error:
ace:src hqin$ make
gcc -O3 -Wall -c -o misc.o misc.c
In file included from misc.c:21:
misc.h:106: error: conflicting types for ‘psort’
/usr/include/stdlib.h:310: error: previous declaration of ‘psort’ was
here
misc.c:748: error: conflicting types for ‘psort’
/usr/include/stdlib.h:310: error: previous declaration of ‘psort’ was
here
make: *** [misc.o] Error 1
After the
#include<stdlib.h>
add
#undef psort
and then
#include "misc.h"
The "#undef psort" stops the psort being referenced from “stdlib.h”
so it can be referenced from "misc.h" and that makes for a happy
compiler.
It might be worth a try, but I doubt it will help. From the
wording of the error messages, it looks like `psort' has been
declared as an ordinary identifier, not as (or not only as) a
macro. The #undef will erase a macro definition, if there is
one, but will not affect the visibility of the plain identifier:
int x;
#undef x
double x; // error, despite the #undef
You are trying to undef a variable not a function.
#undef does not apply to variables nor to functions, but to
macros. At the time #undef is processed (and at the time macros
are expanded), there is no difference between a "variable" and
a "function." Not even `int' has any meaning beyond than "I am a
three-character token."
#undef psort
It is called function overriding and it does work and has for me since
my turbo c days.
I have no personal experience with Turbo C. However, no C
compiler I've ever used has processed #undef any differently for
macros whose names look like functions than for macros whose
names look like something else. Certainly no Standard-conforming
compiler has ever done so.
Rather than ruminating just try it. The thing to remember is that the
#undef is only valid for the source file it appeares in.
Good advice. What happened when you tried it?
It seems to work. Try my example.
#include<stdio.h>
#include<stdlib.h>
#undef printf
/*
** int printf (const char*, ...);
*/
int printf(const char* str, ...)
Try `void printf(int *foo, double bar)' here, and perhaps you'll
see what I mean. (But also see below.)
{
fprintf(stdout, "12345");
return 0;
}
int main()
{
printf("Hello world!\n");
return 0;
}
If the output is "12345" then my own version of printf is used and not
the library version. I got "12345". Had I got "Hello world!" then I
would be wrong and you would be right.
Since the program's behavior is undefined (7.1.3p2, also 7.19.2p2),
few useful conclusions can be drawn from it. It could have printed
"12345" or "Hello world!" or "Eat Bertha's Mussels" or done something
even stranger. The C Standard makes no guarantees or assurances about
this program; it washes its hands.
Also note that my implimentation uses the exact same declaration as in
the header file.
... meaning that it's of no help to the O.P., whose code has a
declaration that conflicts with the header's. Try the experiment
suggested above.
It's also true that <stdlib.h> has no right to declare the O.P.'s
identifier. Since it does, we conclude that the implementation is
non-conforming, so arguments that begin with "The Standard says ..."
are already suspect. The implementation is non-conforming in this
respect, and may well be non-conforming in others: we're all guessing.
Perhaps its `int' has a fractional part, who knows?
"#undef printf" means do not link the libray version, link the
supplied version, it has nothing to do with header files.
`#undef printf' means *only* "If there is a macro named `printf',
function-like or object-like, with any expansion whatever, remove
that macro." It means nothing at all about linkage, nothing about
versions, nothing about ownership, nothing, nothing, *nothing* else.
... in C, that is, as opposed to whatever language the O.P.'s
compiler translates.