How can I know it is a macro or actually is a function?

S

Shi Jin

Hi there,

While I was trying to disassemble a simple C program for my OS course, I
found that the call to function longjmp is actually called to siglongjmp
under linux.

And similarly, under windows XP, call to setjmp and longjmp are called to
_setjmp3 and _longjmp respectively. Somebody told me they are macros.

Then I want to ask, how can I know the thing I am looking at is a macro or
not? If it is, how to find out the real guy that is doing the job?

Thanka a lot.

Shi
 
J

Jack Klein

Hi there,

While I was trying to disassemble a simple C program for my OS course, I
found that the call to function longjmp is actually called to siglongjmp
under linux.

And similarly, under windows XP, call to setjmp and longjmp are called to
_setjmp3 and _longjmp respectively. Somebody told me they are macros.

Then I want to ask, how can I know the thing I am looking at is a macro or
not? If it is, how to find out the real guy that is doing the job?

Thanka a lot.

Shi

The first thing that you can do is buy and read a copy of the
standard. setjmp is required to be a macro.

There is really no way to tell about library functions in general,
however, because the C standard allows an implementation to provide a
macro version of any and all standard library functions.

On the other hand, an implementation is also required to provide
actual function versions of all standard library functions that are
required to be functions (not setjmp, which is specifically not a
function). You can force the implementation to call the function
version rather than expand the macro by putting parentheses around the
name of the function:

size_t the_size = strlen(a_char_pointer); /* could use a macro */

size_t the_size = (strlen)(a_char_pointer); /* can't be macro */

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
C

Capstar

Jack said:
The first thing that you can do is buy and read a copy of the
standard. setjmp is required to be a macro.

There is really no way to tell about library functions in general,
however, because the C standard allows an implementation to provide a
macro version of any and all standard library functions.

If you really want to know if something is a macro or not, you could try
to use the preprocessor of your compiler to get all the macros expanded.
You need to be able to call your preprocessor only ofcourse. Read your
compiler documentation on how to do this.
Be prepared to do some searching in the result, because preprocessed
code is usually somewhat harder to read. That's probably why macros were
invented.

Mark
 
M

Manik Raina

Then I want to ask, how can I know the thing I am looking at is a macro or
not? If it is, how to find out the real guy that is doing the job?


<OT>

For just this part of your question (irrespective of what Jack said
held or not) there could be two ways

1. Since you're using linux (which would most likely mean you're using
gcc) , you could compile code as gcc -E to see the post processor output.

2. You could check the symbol table using nm or objdump. If you compare
the dumps when you use the macro and when you don't , you can notice
some functions showing up in the dump which are most likely what the
macro expands to...

</OT>
 
L

Larry__Weiss

Jack said:
On the other hand, an implementation is also required to provide
actual function versions of all standard library functions that are
required to be functions (not setjmp, which is specifically not a
function). You can force the implementation to call the function
version rather than expand the macro by putting parentheses around the
name of the function:
size_t the_size = strlen(a_char_pointer); /* could use a macro */
size_t the_size = (strlen)(a_char_pointer); /* can't be macro */

When an actual function is used by the implementation for a standard
library function, is the implementation required to use the same
function for all calls to that function?

- Larry Weiss
 
P

pete

Larry__Weiss said:
When an actual function is used by the implementation for a standard
library function, is the implementation required to use the same
function for all calls to that function?

It's possible for the epression:
("identical string literal" == "identical string literal")
to be either true or false, because the standard explicitly
says that identical string literals need not be stored
in the same memory.

I would expect that the expression:
(&function_name == &function_name)
would always be true,
in the absence of any wording to the contrary.
 
K

Kevin Easton

Shi Jin said:
Hi there,

While I was trying to disassemble a simple C program for my OS course, I
found that the call to function longjmp is actually called to siglongjmp
under linux.

And similarly, under windows XP, call to setjmp and longjmp are called to
_setjmp3 and _longjmp respectively. Somebody told me they are macros.

Then I want to ask, how can I know the thing I am looking at is a macro or
not? If it is, how to find out the real guy that is doing the job?

I'm far from a preprocessor guru so this probably doesn't work
everywhere... but it seems to work for me:

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

#define STR(X) #X
#define STR2(X) STR(X)

#define TEST_IT(X) \
do { \
if (strcmp(#X "(0)", STR2(X(0))) == 0) \
printf(STR(X) " is a function.\n"); \
else \
printf(STR(X) " is a macro.\n"); \
} while (0)

int main()
{
TEST_IT(main);
TEST_IT(printf);
TEST_IT(getc);
TEST_IT(longjmp);

return 0;
}

...and produces output like:

main is a function.
printf is a function.
getc is a macro.
longjmp is a function.

- Kevin.
 
J

Jack Klein

When an actual function is used by the implementation for a standard
library function, is the implementation required to use the same
function for all calls to that function?

- Larry Weiss

That's an interesting question, and my guess would be no. The
standard only defines the interface to standard library functions and
defines the results (within certain implementation-defined limits)
when if is called correctly with valid arguments.

That is one reason why an implementation is allowed to replace these
functions with macros, as long as the results when used properly are
absolutely the same as far as a strictly conforming program is able to
determine.

So while it would seem quite inefficient, an implementation could have
functions named, for example, __strlen1 through __strlen6 inclusive,
and select among them in any order, or at random, when compiling a
program that contained multiple calls to strlen(). As long as they
all produced the same results.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jack Klein

If you really want to know if something is a macro or not, you could try
to use the preprocessor of your compiler to get all the macros expanded.
You need to be able to call your preprocessor only ofcourse. Read your
compiler documentation on how to do this.
Be prepared to do some searching in the result, because preprocessed
code is usually somewhat harder to read. That's probably why macros were
invented.

Mark

....and there is no way to do this under standard C, which does not
require an implementation to invoke a preprocessor only, not that such
an invocation, if it exists, produce a human-readable text file.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
C

Capstar

Jack said:
...and there is no way to do this under standard C, which does not
require an implementation to invoke a preprocessor only, not that such
an invocation, if it exists, produce a human-readable text file.

Why is there no way to do this under standard C? As Manik pointed out
you can for instance use gcc -E to create a preprocessed output. Maybe
the standard doesn't say a preprocessor only invocation should exist,
but therefor it is not impossible to do it.
And a preprocessor does create a human readble text file. It is not easy
to read, but is is readable.

Mark
 
P

Peter Shaggy Haywood

Groovy hepcat Shi Jin was jivin' on Sun, 07 Sep 2003 23:06:01 -0400 in
comp.lang.c.
How can I know it is a macro or actually is a function?'s a cool
scene! Dig it!
While I was trying to disassemble a simple C program for my OS course, I
found that the call to function longjmp is actually called to siglongjmp
under linux.

And similarly, under windows XP, call to setjmp and longjmp are called to
_setjmp3 and _longjmp respectively. Somebody told me they are macros.

Then I want to ask, how can I know the thing I am looking at is a macro or
not? If it is, how to find out the real guy that is doing the job?

#ifdef longjmp
/* it's a macro */
#else
/* it's not a macro */
#endif

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
T

Tom Zych

#ifdef longjmp
/* it's a macro */
#else
/* it's not a macro */
#endif

An elegant and in hindsight obvious solution that I wish I'd thought
of. Seems to me it (or any other such test) could be misleading,
though. You'd have to make sure you were in the same context as the
code you're worried about. For example, if you included some headers
in your code, but not in the test program, the results could differ.

Right?
 
L

Lowell Gilbert

Jack Klein said:
That's an interesting question, and my guess would be no. The
standard only defines the interface to standard library functions and
defines the results (within certain implementation-defined limits)
when if is called correctly with valid arguments.

That is one reason why an implementation is allowed to replace these
functions with macros, as long as the results when used properly are
absolutely the same as far as a strictly conforming program is able to
determine.

The standard *does* seem to assume that there's one real function call
implementation, though. I'm referring to language talking about "an
actual function" as opposed to the macro implementation. I don't see
anything that would actually require the single function implementation.
So while it would seem quite inefficient, an implementation could have
functions named, for example, __strlen1 through __strlen6 inclusive,
and select among them in any order, or at random, when compiling a
program that contained multiple calls to strlen(). As long as they
all produced the same results.

I can imagine cases where this sort of thing could be done *for*
efficiency. E.g., a version of strncpy for situations where the
compiler can tell, a priori, that there is a null character within the
specified length.
 
L

Larry__Weiss

Lowell said:
I can imagine cases where this sort of thing could be done *for*
efficiency. E.g., a version of strncpy for situations where the
compiler can tell, a priori, that there is a null character within the
specified length.

The opportunities for optimization is what went through my mind when I
first imagined the possibility for more than one actual function being
instantiated.

earlier:
I would expect that the expression:
(&function_name == &function_name)
would always be true,
in the absence of any wording to the contrary.

Does the Standard address that assertion? If so, what does it say?
If not, does the use of that expression make the program not strictly
conforming?

- Larry Weiss
 
P

pete

Larry__Weiss said:
The opportunities for optimization is what went through my mind when I
first imagined the possibility for more than one actual function being
instantiated.

earlier:
I would expect that the expression:
(&function_name == &function_name)
would always be true,
in the absence of any wording to the contrary.

Does the Standard address that assertion? If so, what does it say?
If not, does the use of that expression make the program not strictly
conforming?

If I'm correctly interpreting the consequences of
a function call to a standard library function,
being able to correspond to any of several related functions,
then it would seem to me that the termination condition
of the following program, invokes unspecified behavior,
which to me, just seems nutty and way out of left field.

/* BEGIN new.c */

#include <stdio.h>
#include <math.h>

#define STOP (cosh)
#define X (3.141592653589793 / 4)

#define PLAY_LIST { \
{sin,"sin"}, \
{cos,"cos"}, \
{tan,"tan"}, \
{asin,"asin"}, \
{acos,"atan"}, \
{sinh,"sinh"}, \
{cosh,"cosh"}, \
{tanh,"tanh"}, \
{exp,"exp"}, \
}

int main(void)
{
struct {
double(*f)(double);
char *w;
} p_l[] = PLAY_LIST, *pointer;

for (pointer = p_l;; ++pointer) {
printf("%s(%f) is %f.\n", pointer -> w, X, pointer -> f(X));
if (pointer -> f == STOP) {
break;
}
}
return 0;
}

/* END new.c */
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top