Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Function-like macro

Reply
Thread Tools

Function-like macro

 
 
Malcolm
Guest
Posts: n/a
 
      05-24-2005

"Russell Shaw" <rjshawN_o@s_pam.netspace.net.au> wrote
> How do i make an if/then/else macro act as a function
> so that the whole thing looks like the return value?
>
> I tried this lame attempt for starters:
>
> #define A_FROM_B(b) \
> ( \
> if(b < 10) { \
> a = b; \
> } \
> else { \
> a = 2*b; \
> }, \
> a; \
> )


#define A_FROM_B(b) ((b) < 10 ? (b) : (2 * (b)))


 
Reply With Quote
 
 
 
 
Dale Hagglund
Guest
Posts: n/a
 
      05-25-2005
Russell> How do i make an if/then/else macro act as a function so
Russell> that the whole thing looks like the return value?

Others have already pointed out that you're probably much better off
using an inline function. It's more easily readable and editable.
That said, GCC does have a non-standard extension that allows you to
do what you want:

#define A_FROM_B(b) \
({ \
int __b = (b); \
int __a; \
if (__b < 10) \
__a = __b; \
else \
__a = 2*__b; \
__a; \
})

A few notes:

* I haven't compiled the above code so I may have a couple of
typos in it. See Statement Exprs in the gcc info pages.

* I introduced the __b variable to prevent multiple evaluation
of b. (Functions get you this for free, of course.)

* The value of the macro is the the last "bare" expression in
the block.

* As I mentioned, as far as I know this is non-standard.

* GCC has a couple of other nifty extensions that work well
together with this extension. Especially see the gcc info
on typeof().

* Because macros are based on textual substitution, it's a
good idea to introduce local variable names that aren't
likely to collide with names used inside the macro
arguments. (Again, functions completely avoid this issue.)

Dale.
 
Reply With Quote
 
 
 
 
Russell Shaw
Guest
Posts: n/a
 
      05-25-2005
Dale Hagglund wrote:
> Russell> How do i make an if/then/else macro act as a function so
> Russell> that the whole thing looks like the return value?
>
> Others have already pointed out that you're probably much better off
> using an inline function. It's more easily readable and editable.
> That said, GCC does have a non-standard extension that allows you to
> do what you want:
>
> #define A_FROM_B(b) \
> ({ \
> int __b = (b); \
> int __a; \
> if (__b < 10) \
> __a = __b; \
> else \
> __a = 2*__b; \
> __a; \
> })
>
> A few notes:
>
> * I haven't compiled the above code so I may have a couple of
> typos in it. See Statement Exprs in the gcc info pages.
>
> * I introduced the __b variable to prevent multiple evaluation
> of b. (Functions get you this for free, of course.)
>
> * The value of the macro is the the last "bare" expression in
> the block.
>
> * As I mentioned, as far as I know this is non-standard.
>
> * GCC has a couple of other nifty extensions that work well
> together with this extension. Especially see the gcc info
> on typeof().
>
> * Because macros are based on textual substitution, it's a
> good idea to introduce local variable names that aren't
> likely to collide with names used inside the macro
> arguments. (Again, functions completely avoid this issue.)
>
> Dale.


Interesting, it is in gcc-3.4 info help 5.1 Statements and Declarations in Expressions.

Does a curly-bracket block {...} have a value in standard C? I've been looking for
a long time.

The macro above works (i tested it).
 
Reply With Quote
 
Dale Hagglund
Guest
Posts: n/a
 
      05-25-2005
[My example of gcc statement expression syntax deleted. --rdh]

Russell> Does a curly-bracket block {...} have a value in standard
Russell> C?

Nope. As far as I know its a gcc-only extension.

Dale.
 
Reply With Quote
 
Jens.Toerring@physik.fu-berlin.de
Guest
Posts: n/a
 
      05-25-2005
Russell Shaw <rjshawN_o@s_pam.netspace.net.au> wrote:
> Dale Hagglund wrote:
>> * The value of the macro is the the last "bare" expression in
>> the block.
>>
>> * As I mentioned, as far as I know this is non-standard.


> Interesting, it is in gcc-3.4 info help 5.1 Statements and Declarations in Expressions.


> Does a curly-bracket block {...} have a value in standard C? I've been
> looking for a long time.


No, a block (compound statement) isn't an expression and thus has no
value. So something like

int i = { 1; };

or

int i = ( { 1; } );

or variations of these aren't standard C. gcc lets you use the second
version, i.e. a compound statement enclosed in parentheses where the
value of the last expression in the block is taken to be the value of
of the whole construct, as an extension only (that's why it is listed
in the info pages under "C Extensions"

Regards, Jens
--
\ Jens Thoms Toerring ___ http://www.velocityreviews.com/forums/(E-Mail Removed)-berlin.de
\__________________________ http://www.toerring.de
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      05-26-2005
Dale Hagglund <(E-Mail Removed)> wrote:

> Others have already pointed out that you're probably much better off
> using an inline function. It's more easily readable and editable.
> That said, GCC does have a non-standard extension that allows you to
> do what you want:
>
> #define A_FROM_B(b) \
> ({ \
> int __b = (b); \
> int __a; \
> if (__b < 10) \
> __a = __b; \
> else \
> __a = 2*__b; \
> __a; \
> })


> * I introduced the __b variable to prevent multiple evaluation
> of b. (Functions get you this for free, of course.)


Unfortunately it also makes the macro non-portable, since all
identifiers starting with __ (or _ plus capital letter) are reserved for
the implementation. __b is simple enough that it could clash with
something defined in a system header.

> * As I mentioned, as far as I know this is non-standard.


'tis.

> * Because macros are based on textual substitution, it's a
> good idea to introduce local variable names that aren't
> likely to collide with names used inside the macro
> arguments. (Again, functions completely avoid this issue.)


But make sure they're yours to use.

Richard
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      05-27-2005
Richard Bos wrote:

> #define A_FROM_B(b) ((b)<10? (b): 2*(b))
>
> Note the parens around b in the definition of the macro.
> They will save
> your bacon some day when you decide to call A_FROM_B(x+10).


Trivia point:
Only the first and last pair are needed for bacon saving.

#define A_FROM_B(b) ((b) < 10 ? b : 2 * (b))

? b :
means the same thing as
?(b):

--
pete
 
Reply With Quote
 
Richard Bos
Guest
Posts: n/a
 
      05-27-2005
pete <(E-Mail Removed)> wrote:

> Richard Bos wrote:
>
> > #define A_FROM_B(b) ((b)<10? (b): 2*(b))
> >
> > Note the parens around b in the definition of the macro.
> > They will save
> > your bacon some day when you decide to call A_FROM_B(x+10).

>
> Trivia point:
> Only the first and last pair are needed for bacon saving.
>
> #define A_FROM_B(b) ((b) < 10 ? b : 2 * (b))
>
> ? b :
> means the same thing as
> ?(b):


In this case, perhaps. Howsoever, I'd advise getting into the habit of
parenthesisising anyway, for psychobabblical reasons.

Richard
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dedicated Macro or Normal Macro? John Ortt Digital Photography 5 11-22-2005 12:43 PM
Macro lens on a camera with a macro setting??? mitchell.chris@gmail.com Digital Photography 2 09-28-2005 07:55 AM
in S.E. Asia : Canon EOS 300d with 100 macro ED vs. Nikon D70 with Nikon 105 macro ? J. Cod Digital Photography 0 09-29-2004 05:46 AM
#define macro to enclose an older macro with strings Dead RAM C++ 20 07-14-2004 10:58 AM
macro name from macro? D Senthil Kumar C Programming 1 09-21-2003 07:02 PM



Advertisments