473,387 Members | 1,876 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

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

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

Nov 13 '05 #1
13 2255
On Sun, 07 Sep 2003 23:06:01 -0400, "Shi Jin" <ji********@hotmail.com>
wrote in comp.lang.c:
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
Nov 13 '05 #2
Jack Klein wrote:
On Sun, 07 Sep 2003 23:06:01 -0400, "Shi Jin" <ji********@hotmail.com>
wrote in comp.lang.c:

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.


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

Nov 13 '05 #3
> 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>
Nov 13 '05 #4
Jack Klein wrote:
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
Nov 13 '05 #5
Larry__Weiss wrote:

Jack Klein wrote:
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?


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.

--
pete
Nov 13 '05 #6
Shi Jin <ji********@hotmail.com> wrote:
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.
Nov 13 '05 #7
On Mon, 08 Sep 2003 11:57:01 -0500, Larry__Weiss <lf*@airmail.net>
wrote in comp.lang.c:
Jack Klein wrote:
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


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
Nov 13 '05 #8
On Mon, 08 Sep 2003 10:49:08 +0200, Capstar <sp***@eg.homeip.net>
wrote in comp.lang.c:
Jack Klein wrote:
On Sun, 07 Sep 2003 23:06:01 -0400, "Shi Jin" <ji********@hotmail.com>
wrote in comp.lang.c:

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.


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
Nov 13 '05 #9
Jack Klein wrote:
On Mon, 08 Sep 2003 10:49:08 +0200, Capstar <sp***@eg.homeip.net>
wrote in comp.lang.c:

Jack Klein wrote:

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.


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

Nov 13 '05 #10
Peter Shaggy Haywood wrote:
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


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?

--
Tom Zych
This email address will expire at some point to thwart spammers.
Permanent address: echo 'g******@cbobk.pbz' | rot13
Nov 13 '05 #11
Jack Klein <ja*******@spamcop.net> writes:
On Mon, 08 Sep 2003 11:57:01 -0500, Larry__Weiss <lf*@airmail.net>
wrote in comp.lang.c:
Jack Klein wrote:
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


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.
Nov 13 '05 #12
Lowell Gilbert wrote:
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.

"pete" wrote 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
Nov 13 '05 #13
Larry__Weiss wrote:

Lowell Gilbert wrote:
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.

"pete" wrote 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 */
--
pete
Nov 13 '05 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Pete | last post by:
In Access 95/97 I used to be able to create pull down menus (File,Edit ...) from a macro. It seems there used to be some wizard for that. However in Access 2000 it seems you have to build your...
10
by: Karim Thapa | last post by:
Why following macro does not work? #define removebrace(x) x void Foo(int a, int b, char *txt, int d, int e); main() {
8
by: lasek | last post by:
Hi...in some posts i've read...something about using macro rather then function...but difference ??. Best regards....
5
by: Bill | last post by:
This database has no forms. I am viewing an Access table in datasheet view. I'd like to execute a macro to execute a function (using "runcode"). In the function, I'll reading data from the record...
1
by: Chris Thomasson | last post by:
I was wondering if the following technique will produce undefined behavior: _______________ #include <cstdio> #define CALL_MACRO_FUNCTION(func_ptr)func_ptr() #define MY_MESSAGE() "Press...
6
by: jason | last post by:
Hi, I learned my lesson about passing pointers, but now I have a question about macros. Why does the function work and the MACRO which is doing the same thing on the surface, does not work in...
1
by: todWulff | last post by:
Good day folks. Let me open with the statement that I am not a C++/C programmer. The environment that I am programming in is ARMbasic, an embedded BASIC targeted toward ARM-based...
16
by: mdh | last post by:
I have asked a few questions about Macros...and think what I have been missing ...and which all who have replied clearly understand...is that this is a Pre-processor action. Hopefully the above is...
36
by: sh.vipin | last post by:
how to make large macro paste the code as it is Problem Explanation '-- For example in the program below /* a.c - starts here */ #define DECL_VARS() \ unsigned int a0;\ unsigned int a1;\...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.