redefine a function with a same name

J

Joe Wright

hi all
I want to redefine a function getchar() in header stdio.h ,but I don't
know what should I do.
Hi yourself. Try again to explain what you want to accomplish. The
function getchar() is defined in libc or whatever. It is only described
(protoyped) in stdio.h.

You can't 'redefine' a library function. What you can do is write
(define) your own function and then lie like hell so that ..

c = getchar();

... will actually call your function instead of the standard one. Is this
what you want to do?
 
R

Richard Bos

Morris Dovey said:
Richard Bos (in (e-mail address removed)4all.nl) said:

| (e-mail address removed) wrote:
|
|| I want to redefine a function getchar() in header stdio.h ,but I
|| don't know what should I do.
|
| You should ask in a newsgroup dedicated to your particular compiler
| suite, since in the general case the ISO C Standard declares this to
| cause undefined behaviour.

[ Original post never showed up at my server ]

You can portably redefine standard library function invocations; but
shouldn't tamper with the standard header files.

At the link below is an example where calloc(), malloc(), realloc(),
and free() have been redefined in a in order to produce a debug
trace - but note that stdlib.h hasn't been touched.

From n1124, 7.1.3#1 - emphasis mine:

# — Each identifier with file scope listed in any of the following
# subclauses (including the future library directions) is reserved for
# use _as_a_macro_name_ and as an identifier with file scope in the
# same name space if any of its associated headers is included.

and #3:

# 3 If the program removes (with #undef) any macro definition of an
# identifier in the first group listed above, the behavior is
# undefined.

So yes, it's undefined behaviour. It's not very likely to cause real
problems anywhere, but it's not defined.

Richard
 
M

Morris Dovey

Richard Bos (in (e-mail address removed)4all.nl) said:

| From n1124, 7.1.3#1 - emphasis mine:
|
| #  Each identifier with file scope listed in any of the following
| # subclauses (including the future library directions) is
| reserved for # use _as_a_macro_name_ and as an identifier with
| file scope in the # same name space if any of its associated
| headers is included.
|
| and #3:
|
| # 3 If the program removes (with #undef) any macro definition of an
| # identifier in the first group listed above, the behavior is
| # undefined.
|
| So yes, it's undefined behaviour. It's not very likely to cause real
| problems anywhere, but it's not defined.

Good catch! I missed that one - and although I haven't heard of it
causing problems for anyone (which is what you expected), I should at
least add a warning to the prologs that the #undef's may produce
undefined behavior on some systems.

Thanks!
 
T

Tom Rauschenbach

You will be.

First, editing the header file doesn't redefine any functions, always
supposing you can do it.

Second, if the OP is J Random Unix User, they won't be able to edit
/usr/include/stdio.h, because they won't have permission to do so.

Third, if the OP is J Random RISC OS User, there /isn't/ a file
called /usr/include/stdio.h, there isn't a directory called
/usr/include, there isn't a directory called /usr, and there isn't
a directory called /.

Fourth, in any case the standard includes need not be "files" /at
all/, so there may be nothing to edit except the compiler
executable. The term "playing with fire" doesn't begin to cover
it.

Finally, even if you /can/ do any of this, it's very likely you
shouldn't. `getchar` is supposed to do what `getchar` is supposed
to do - and people use it to do that.



Isn't this really a question about the link editor ? It sounds to me like
the OP wants to replace a standard library function with his own. Very
little to do with C, I think.
 
D

Dave Thompson

Anyway, what's the accepted wisdom about doing the following?
(Is it at least well defined?)

-------------
#include <stdio.h>

int mygetchar (void)
{
printf ("My getchar\n");
return getchar();
}

#define getchar() mygetchar()
All standard library functions can be #define'd as function-like
macros by the header that declares (prototypes) them, and getchar() in
particular pretty commonly is. It is a constraint violation and a
required diagnostic to re-#define an existing macro differently.
You need to #undef getchar first. Note that you don't need to put it
in #ifdef to be safe -- #undef of a nonmacro is a guaranteed no-op.

Given you do that, it should as you want go through your replacement.
7.1.3p1 does say it is 'reserved for use as a macro name' without
mentioning #undef, but p3 says that #undef of _[A-Z_]* gives U.B.
without saying the same for any other standard-reserved identifiers,
and 7.1.4p1 says that #undef of such a 'shadow' macro will allow
access to the real function; it doesn't make sense to do that without
also allowing you to #define it for your own use.

Note however that (other) <stdio.h> shadow macros could legally use
each other, including getchar() expecting to get the standard one, and
get your replacement instead. For just a wrapper like this it should
still work, but if you try to rewrite a std lib function to do
something different (and IYO better) you are courting trouble.

Whether this sort of thing is _wise_ is a whole other question.
Personally I would rather use a debugger in most cases where this
might possibly be of any use. And in the cases where a debugger
doesn't work, printf (or more generally stdout) may not be the right
answer. But that just opens up _barrels_ of worms.
int main (void)
{
char c = getchar ();
printf ("got char '%c'\n", c);
return 0;
}
<pedantic> plain char may be signed and unable to correctly represent
some values returned from getchar(), including EOF, even when
converted back to unsigned char by %c inside *printf. In most cases
including this use int. But I'm sure that wasn't your point.


- David.Thompson1 at worldnet.att.net
 
D

Dave Thompson

From n1124, 7.1.3#1 - emphasis mine:

# — Each identifier with file scope listed in any of the following
# subclauses (including the future library directions) is reserved for
# use _as_a_macro_name_ and as an identifier with file scope in the
# same name space if any of its associated headers is included.

and #3:

# 3 If the program removes (with #undef) any macro definition of an
# identifier in the first group listed above, the behavior is
# undefined.

So yes, it's undefined behaviour. It's not very likely to cause real
problems anywhere, but it's not defined.
I believe 'first group above' means the first dash item in p1: "All
identifiers that begin with an underscore and either an uppercase
letter or another underscore are always reserved for any use."

getchar(), and most other std-lib functions (except _Exit and maybe
another I've forgotten), do not fall into this group; they are in the
item you quoted, which is the fifth.

7.1.4p1 explicitly promises you can 'bypass' a shadowing macro
by using (func) (args) or by #undef, implicitly without any U.B.
Although this does not clearly promise you can re-#define it.


- David.Thompson1 at worldnet.att.net
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top