473,324 Members | 2,531 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,324 software developers and data experts.

standard functions as macros

This question might be OT I apologise if it is.

All functions are allowed to be macros.
In a hypothetical implementation a tolower might be written as:

#define tolower(x) \
(x) == 'A' ? 'a' : \
(x) == 'B' ? 'b' : \
/* etc */
(x) == 'Z' ? 'z' : (x)

Ofcourse this has other problems (example if you pass i++ to it) but
we don't care about that now.

What I care about is 2 things:

o How does the compiler warn about incorrect arguments passed/etc?
Normally the preprocessor will change the source code, for example:

int add_one(int x);
#define add_one(x) ((x)+1)
/* ... */
char foo[2];
char * p = foo;
char * s = add_one(p); /* at this point, the compiler won't see a
'call to add_one since it would be replaced by the pp. */

o How does the macro work if I don't pass any arguments?
example:
int foo(unsigned x);
#define foo(x) (~(x))
/* ... */
int (*ptr)(void) = foo; /* how does that work? */

My tolower() macro example would not work in both cases.
thank you for your answers
Jan 4 '08 #1
7 1439
On Jan 4, 2:02 pm, vipps...@gmail.com wrote:
o How does the macro work if I don't pass any arguments?
example:
int foo(unsigned x);
#define foo(x) (~(x))
/* ... */
int (*ptr)(void) = foo; /* how does that work? */
What I ment here is int (*ptr)(int), I changed the function while I
was posting but I forgot to change ptr.
Jan 4 '08 #2
vi******@gmail.com wrote:
All functions are allowed to be macros.
With caveats.
In a hypothetical implementation a tolower might be written as:

#define tolower(x) \
(x) == 'A' ? 'a' : \
(x) == 'B' ? 'b' : \
/* etc */
(x) == 'Z' ? 'z' : (x)

Ofcourse this has other problems (example if you pass i++ to it) but
we don't care about that now.

What I care about is 2 things:

o How does the compiler warn about incorrect arguments passed/etc?
Depends on the implementation
Normally the preprocessor will change the source code, for example:

int add_one(int x);
#define add_one(x) ((x)+1)
/* ... */
char foo[2];
char * p = foo;
char * s = add_one(p); /* at this point, the compiler won't see a
'call to add_one since it would be replaced by the pp. */
Some implementations will remember this, and use the proper name to
complain. Some will not.
o How does the macro work if I don't pass any arguments?
example:
int foo(unsigned x);
#define foo(x) (~(x))
/* ... */
int (*ptr)(void) = foo; /* how does that work? */
This, at least, works: the macro foo is not the same macro as foo().

Richard
Jan 4 '08 #3
On Jan 4, 2:18 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
This, at least, works: the macro foo is not the same macro as foo().
Ah, this is what I had in mind too, therefore the implementation must
provide a function pointer 'x' that does the equivalent of the macro
'x()'.
Thanks for clearing this Richard.
Jan 4 '08 #4
vi******@gmail.com wrote:
On Jan 4, 2:18 pm, r...@hoekstra-uitgeverij.nl (Richard Bos) wrote:
>This, at least, works: the macro foo is not the same macro as foo().
Ah, this is what I had in mind too, therefore the implementation must
provide a function pointer 'x' that does the equivalent of the macro
'x()'.
This is explicitly required by the standard for any standard library
function implemented as a function-like macro. Note, however, that some
standard library features are explicitly described as function-like
macros, such as in <stdarg.h>. In those cases, there is no underlying
function that can be called.
Jan 4 '08 #5
vippstar wrote:
This question might be OT I apologise if it is.

All functions are allowed to be macros.
In a hypothetical implementation a tolower might be written as:

#define tolower(x) \
(x) == 'A' ? 'a' : \
(x) == 'B' ? 'b' : \
/* etc */
(x) == 'Z' ? 'z' : (x)

Ofcourse this has other problems (example if you pass i++ to it) but
we don't care about that now.
No. Macro implementations are required to evaluate each argument exactly
once, and to have enough parentheses.
What I care about is 2 things:

o How does the compiler warn about incorrect arguments passed/etc?
Normally the preprocessor will change the source code, for example:

int add_one(int x);
#define add_one(x) ((x)+1)
/* ... */
char foo[2];
char * p = foo;
char * s = add_one(p); /* at this point, the compiler won't see a
'call to add_one since it would be replaced by the pp. */
So what? Of course, the macro implementation of a standard library
function must have the right type, so it'd be ((int)(x)+1). So the
compiler *can* see that there's something wrong.
o How does the macro work if I don't pass any arguments?
example:
int foo(unsigned x);
#define foo(x) (~(x))
/* ... */
int (*ptr)(void) = foo; /* how does that work? */
The identifier foo gets replaced by the preprocessor only if immediately
followed by a ( token. ("Immediately" here includes the case in which
there is whitespace/comments between them.)

--
Army1987 (Replace "NOSPAM" with "email")
Jan 4 '08 #6
Army1987 wrote:
>
vippstar wrote:
This question might be OT I apologise if it is.

All functions are allowed to be macros.
In a hypothetical implementation a tolower might be written as:

#define tolower(x) \
(x) == 'A' ? 'a' : \
(x) == 'B' ? 'b' : \
/* etc */
(x) == 'Z' ? 'z' : (x)

Ofcourse this has other problems (example if you pass i++ to it) but
we don't care about that now.
No. Macro implementations are required to
evaluate each argument exactly once,
and to have enough parentheses.
putc and getc macros
may evaluate their stream argument more than once.

--
pete
Jan 4 '08 #7
On Fri, 04 Jan 2008 17:30:07 -0500, pete wrote:
Army1987 wrote:
>vippstar wrote:
#define tolower(x) \
(x) == 'A' ? 'a' : \
(x) == 'B' ? 'b' : \
/* etc */
(x) == 'Z' ? 'z' : (x)

Ofcourse this has other problems (example if you pass i++ to it) but
we don't care about that now.
No. Macro implementations are required to evaluate each argument
exactly once,
and to have enough parentheses.

putc and getc macros
may evaluate their stream argument more than once.
assert is a macro and may not evaluate its argument at all, depending on
NDEBUG.

But that's because special permissions or requirements are explicitly
stated. Since no such special permissions or requirements apply to
tolower, the general requirements apply, which do state each argument
must be evaluated exactly once.
Jan 4 '08 #8

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

Similar topics

5
by: Ross A. Finlayson | last post by:
Hi, I'm scratching together an Access database. The development box is Office 95, the deployment box Office 2003. So anyways I am griping about forms and global variables. Say for example...
3
by: Kevin Goodsell | last post by:
I've found something that looks like an error in n869. Can anyone with the actual standard tell me if it's different there? I'd also be interested if anyone knows of a defect report addressing...
33
by: Robert Seacord | last post by:
When writing C99 code is a reasonable recommendation to use inline functions instead of macros? What sort of things is it still reasonable to do using macros? For example, is it reasonable to...
22
by: David Mathog | last post by:
One thing that keeps coming up in this forum is that standard C lacks many functions which are required in a workstation or server but not possible in an embedded controller. This results in a...
47
by: Thierry Chappuis | last post by:
Hi, I'm interested in techniques used to program in an object-oriented way using the C ANSI language. I'm studying the GObject library and Laurent Deniau's OOPC framework published on his web...
12
by: sam_cit | last post by:
Hi Everyone, I have few questions on inline functions, when i declare a function as inline, is it for sure that the compiler would replace the function call with the actual body of the function?...
7
by: Francine.Neary | last post by:
This may well be implementation-defined or undefined behavior... if so, then of course that's a good enough answer. Consider the following situation: /* file1.c */ int (*f)(const char *,...
31
by: Francine.Neary | last post by:
One interesting thing to come out of the recent "Alignment" thread is that it is impossible to write a portable replacement for malloc in "user space" (not sure what the right term is - I mean an...
38
by: Chris Thomasson | last post by:
Here is some example code for a container API for this group to use: http://appcore.home.comcast.net/web/ as-per the following posts: ...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.