Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Simple Macro Function Pointer Trick...

36 views
Skip to first unread message

Chris Thomasson

unread,
Sep 14, 2007, 10:16:56 AM9/14/07
to
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 <ENTER> to exit."

int main(void) {
puts(CALL_MACRO_FUNCTION(MY_MESSAGE));
getchar();
return 0;
}

_______________


I define 'MY_MESSAGE' as a macro function and only pass the name of it to
'CALL_MACRO_FUNCTION' which in turn uses the name to actually invoke it. The
name of a macro function is analogous to a function pointer. This is useful
when you need to have precise control over when a macro will actually
expand.


--
Chris M. Thomasson
http://appcore.home.comcast.net

James Kanze

unread,
Sep 15, 2007, 4:41:30 AM9/15/07
to
On Sep 14, 4:16 pm, "Chris Thomasson" <cris...@comcast.net> wrote:
> 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 <ENTER> to exit."

> int main(void) {
> puts(CALL_MACRO_FUNCTION(MY_MESSAGE));
> getchar();
> return 0;
> }
> _______________

Not related to your actual question, but the above shouldn't
compile with a conformant implementation of <cstdio>. puts and
getchar should be in std, and no where else. (I don't think any
of the implementations are conformant in this regard. But
what's the point of using <cstdio> instead of <stdio.h>, unless
you expect the functions to be in std::.)

> I define 'MY_MESSAGE' as a macro function and only pass the
> name of it to 'CALL_MACRO_FUNCTION' which in turn uses the
> name to actually invoke it. The name of a macro function is
> analogous to a function pointer. This is useful when you need
> to have precise control over when a macro will actually
> expand.

It should work. When expanding a macro, the preprocessor
rescans the substituted text for further expansions, and it only
recognizes a function style macro if the name is immediately
followed by an opening parentheses. (Thus, for example, in C,
getchar could be a function style macro. But in expressions
like:
int (* pf)() = &getchar ;
or
(getchar)() ;
the macro is not recognized, and the actual function which it
hides is used.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Chris Thomasson

unread,
Sep 17, 2007, 4:50:58 AM9/17/07
to
"James Kanze" <james...@gmail.com> wrote in message
news:1189845690.6...@n39g2000hsh.googlegroups.com...

On Sep 14, 4:16 pm, "Chris Thomasson" <cris...@comcast.net> wrote:
>> I was wondering if the following technique will produce undefined
>> behavior:
>> _______________
>> #include <cstdio>
[...]
>> _______________

> Not related to your actual question, but the above shouldn't
> compile with a conformant implementation of <cstdio>.

[...]

DOH! Ah crap. Of course your correct. Here is some better code:

________________
#include <cstdio>

#define CALL_MACRO_FUNCTION(func_ptr)func_ptr()

#define MY_MESSAGE() "Press <ENTER> to exit."

int main(void) {
{
using namespace std;
puts(CALL_MACRO_FUNCTION(MY_MESSAGE));
getchar();
}

return 0;
}

________________


>> I define 'MY_MESSAGE' as a macro function and only pass the
>> name of it to 'CALL_MACRO_FUNCTION' which in turn uses the
>> name to actually invoke it. The name of a macro function is
>> analogous to a function pointer. This is useful when you need
>> to have precise control over when a macro will actually
>> expand.

> It should work.

Yeah. I agree. BTW, thank you for you response.

0 new messages