conflict function definition with stdlib.h

I

Ian Collins

It seems to work. Try my example.

#include<stdio.h>
#include<stdlib.h>

#undef printf
/*
** int printf (const char*, ...);
*/

int printf(const char* str, ...)
{
fprintf(stdout, "12345");
return 0;
}

Odds are that does nothing. A real test for conflicts would be:

int printf(const char* str );
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.

Which is what I'd expect. Your linker has used your version rather than
the library version.
Also note that my implimentation uses the exact same declaration as in
the header file.

See above.
"#undef printf" means do not link the libray version, link the
supplied version, it has nothing to do with header files.

No, it is a NOP.
 
K

Keith Thompson

Richard Sanders said:
On 1/16/2011 3:08 PM, Richard Sanders wrote: [...]
#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, ...)
{
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.

And if you got "12345" and I got "Hello world!", who would be right?

I get "Hello world!" with at least one implementation, and "12345" with
at least one other. Your program's behavior is undefined. Which means
that the behavior you're seeing is as valid as any other, and proves
very little.

Try this: remove the "#undef printf" and see if it makes any difference.
Also note that my implimentation uses the exact same declaration as in
the header file.

"#undef printf" means do not link the libray version, link the
supplied version, it has nothing to do with header files.

You are mistaken. "#undef" removes a macro definition; it has nothing
to do with linking.
 
E

Eric Sosman

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.
 
E

Eric Sosman

On Sun, 16 Jan 2011 15:26:11 -0500, Eric Sosman


In my previous post I forgot to aknowledge that if a function is
implimented as a #define then the macro is undefined.

I *think* you're referring to part of 7.1.4p1, but your
assertion is garbled and I'm not sure. Summarizing the salient
points of that paragraph: (1) every Standard library function must
be implemented as an actual function, (2) every Standard library
function may also be implemented as a macro, (3) such a macro, if
it exists, can be suppressed or avoided.
The end result is the same. The library function is not linked and the
custom function is and that is the whole point of it, to be able to
replace library functions with a custom function.

This may be true of your implementation, but it is not true of
all, and not true of C-as-defined. C defines no mechanism for
replacing any part of the implementation, short of moving to a
different implementation altogether. If you (try to) supply your
own printf() or malloc() or abort(), the behavior is undefined:
You can no longer count on *anything* the Standard says, because
you have placed yourself outside the law. (7.1.3p2)

Being outside the law is not entirely bad, *if* you happen to
know the rules of the lawless territory you choose to inhabit. But
different implementations border on different regions of that lawless
land, and when you stray across a border you may find that the rules
have changed without warning.
 
K

Keith Thompson

Ian Collins said:
On 01/17/11 10:31 AM, Richard Sanders wrote: [...]
"#undef printf" means do not link the libray version, link the
supplied version, it has nothing to do with header files.

No, it is a NOP.

If the implementation defines printf() as a macro, "#undef printf" makes
the actual function declaration directly visible. But since any such
macro must behave the same way as the function, yes, it's effectively a
NOP.
 

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
474,083
Messages
2,570,591
Members
47,212
Latest member
RobynWiley

Latest Threads

Top