473,241 Members | 1,553 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,241 software developers and data experts.

Avoiding name collisions in macros

Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \
do { \
int temp = (a); \
(a) = (b); \
(b) = temp; \
} while (0)
Aside from the double evaluation of a and b, this works fine *except*
when either macro parameter a or b is called "temp." What's the best to
design macros to avoid these sort of collisions?

Is this a good candiate for using an identifier from that murky
legal-only-as-a-local-variable set, like _temp?

Thanks for your thoughts,
-Peter

(PS Yes, I know about various tricks with bitwise XOR, but I'm
interested in a general solution)

Nov 14 '05 #1
6 3840
In 'comp.lang.c', Peter Ammon <pe*********@rocketmail.com> wrote:
Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \
Macro parameters have no type (or you mean 'inline').
Please don't retype, but copy and paste.

#define swap(a, b) \
do { \
int temp = (a); \
Hence, the macro name should be 'swap_int', or 'swap_i' or the like...
(a) = (b); \
(b) = temp; \
} while (0)

Aside from the double evaluation of a and b, this works fine *except*
when either macro parameter a or b is called "temp." What's the best to
design macros to avoid these sort of collisions?

Is this a good candiate for using an identifier from that murky
legal-only-as-a-local-variable set, like _temp?


I'm not sure it's legal, hence I prefer to postfix with '_'

#define swap(a_, b_) \
do { \
int temp_ = (a_); \
etc.

A little ugly, I concede...

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
Nov 14 '05 #2


Emmanuel Delahaye wrote:
In 'comp.lang.c', Peter Ammon <pe*********@rocketmail.com> wrote:

Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \ <snip>
Hence, the macro name should be 'swap_int', or 'swap_i' or the like...
If you're going to do that it's presumably because you have different
types you need to swap so you could just pass in the type as an argument
to one macro instead of creating several similair macros, e.g.:

#define swap(type,a,b) \
do { \
type _temp; \
...
<snip>Is this a good candiate for using an identifier from that murky
legal-only-as-a-local-variable set, like _temp?


Yes.

I'm not sure it's legal, hence I prefer to postfix with '_'

#define swap(a_, b_) \
do { \
int temp_ = (a_); \
etc.

A little ugly, I concede...


No need for the underscores on the parameters.

Ed.

Nov 14 '05 #3
Emmanuel Delahaye wrote:
In 'comp.lang.c', Peter Ammon <pe*********@rocketmail.com> wrote:

Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \

Macro parameters have no type (or you mean 'inline').


Oops :)
Please don't retype, but copy and paste.
The code isn't actually C, but the general problem is. But since you
asked...

#define ASSIGN(a, b) do { id _temp = (a); (a)=[(b) retain]; [_temp
release]; } while (0)

#define ASSIGN_COPY(a, b) do { id _temp = (a); (a) = [(b) copy]; [_temp
release]; } while (0)

#define swap(a, b) \

do { \
int temp = (a); \

Hence, the macro name should be 'swap_int', or 'swap_i' or the like...

(a) = (b); \
(b) = temp; \
} while (0)

Aside from the double evaluation of a and b, this works fine *except*
when either macro parameter a or b is called "temp." What's the best to
design macros to avoid these sort of collisions?

Is this a good candiate for using an identifier from that murky
legal-only-as-a-local-variable set, like _temp?

I'm not sure it's legal, hence I prefer to postfix with '_'

#define swap(a_, b_) \
do { \
int temp_ = (a_); \
etc.

A little ugly, I concede...

--
Pull out a splinter to reply.
Nov 14 '05 #4
Groovy hepcat Peter Ammon was jivin' on Fri, 21 May 2004 11:54:41
-0700 in comp.lang.c.
Avoiding name collisions in macros's a cool scene! Dig it!
Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \
do { \
int temp = (a); \
(a) = (b); \
(b) = temp; \
} while (0)

Aside from the double evaluation of a and b, this works fine *except*
when either macro parameter a or b is called "temp." What's the best to
design macros to avoid these sort of collisions?


Try creating some kind of Frankenstein's monster thingie with token
concatenation, maybe. Concatenate the names of the two macro arguments
together (and append or prepend temp or something to avoid the
resulting token being a keyword or something) and use the resulting
token as the variable's identifier. For example:

#include <stdio.h>

#define PASTE_(a, b) a ## b
#define PASTE(a, b) PASTE_(a, b)
#define SWAP(t, a, b) do{t PASTE(PASTE(a, b), temp) = (a); \
(a) = (b); \
(b) = PASTE(PASTE(a, b), temp);}while(0)

int main(void)
{
int x = 1, y = 9;

printf("x = %d, y = %d\n", x, y);
SWAP(int, x, y);
printf("x = %d, y = %d\n", x, y);

return 0;
}

--

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"?
Nov 14 '05 #5
ph******@alphalink.com.au.NO.SPAM (Peter "Shaggy" Haywood) writes:
Groovy hepcat Peter Ammon was jivin' on Fri, 21 May 2004 11:54:41
-0700 in comp.lang.c.
Avoiding name collisions in macros's a cool scene! Dig it!
Let's say I need to swap two int values frequently. I would write a macro:

#define swap(int a, int b) \
do { \
int temp = (a); \
(a) = (b); \
(b) = temp; \
} while (0)

Aside from the double evaluation of a and b, this works fine *except*
when either macro parameter a or b is called "temp." What's the best to
design macros to avoid these sort of collisions?


Try creating some kind of Frankenstein's monster thingie with token
concatenation, maybe. Concatenate the names of the two macro arguments
together (and append or prepend temp or something to avoid the
resulting token being a keyword or something) and use the resulting
token as the variable's identifier. For example:

#include <stdio.h>

#define PASTE_(a, b) a ## b
#define PASTE(a, b) PASTE_(a, b)
#define SWAP(t, a, b) do{t PASTE(PASTE(a, b), temp) = (a); \
(a) = (b); \
(b) = PASTE(PASTE(a, b), temp);}while(0)

int main(void)
{
int x = 1, y = 9;

printf("x = %d, y = %d\n", x, y);
SWAP(int, x, y);
printf("x = %d, y = %d\n", x, y);

return 0;
}


This technique only works if the second and third macro arguments are
identifiers. Otherwise, the pasting doesn't yield a valid preprocessor
token, e.g.

int a [] = {1, 9};
SWAP (int, a [0], a [1]);

doesn't work.

It also "pollutes" the namespace with `PASTE' and `PASTE_'. If that is
acceptable, why not go for the following much simpler solution:

#define SWAP(t, a, b) do { t PASTE = (a); \
(a) = (b); \
(b) = PASTE; } while (0)

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #6
In article <news:cu*************@zero-based.org>
Martin Dickopp <ex****************@zero-based.org> writes:
[The token-pasting] technique [using the names of the variables
to be swapped] only works if the second and third macro arguments are
identifiers. Otherwise, the pasting doesn't yield a valid preprocessor
token, e.g.

int a [] = {1, 9};
SWAP (int, a [0], a [1]);

doesn't work.
Indeed.
It also "pollutes" the namespace with `PASTE' and `PASTE_'. If that is
acceptable, why not go for the following much simpler solution:

#define SWAP(t, a, b) do { t PASTE = (a); \
(a) = (b); \
(b) = PASTE; } while (0)


My usual method is just to write such swaps in-line, e.g., when
expanding a specialized sort function in C (in C++ one would just
use templates; and in Ada one would use generics, and so on; in
these languages the problem has a "language-preferred" solution).
If for some reason a swap macro appeals, one could perhaps do away
with the "type" parameter entirely, and supply instead a "temporary
variable" parameter:

#define SWAP(t, a, b) (t = (a), (a) = (b), (b) = t)
...
int a[N];
int swaptmp;
...
SWAP(swaptmp, a[i], a[j]); /* cf. SWAP(int, a[i], a[j]) */

In this version of the macro, I deliberately did not parenthesize
occurrences of the name "t" because it is supposed to be a simple
variable of the appropriate type.

If one wishes to reduce the scope of the variable to just the braces
introduced by a do-while(0) (e.g., to assist a compiler in
optimization) there is another variant of this method:

#define SWAP(t, v, a, b) \
do { t v = (a); (a) = (b); (b) = v; } while (0)
...
SWAP(int, swaptmp, a[i], a[j]);

So far, however, it has been my experience that compilers smart
enough to optimize swaps into machine-level XCHG instructions (or
equivalent) are also smart enough to do dataflow and lifetime
analysis on variables, so that they can already determine that
the "swaptmp" variable's value persists only for the one source
line.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #7

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

Similar topics

37
by: hasadh | last post by:
Hello, probably this may be a simple qn to u all but I need an answer plz. In my software i used macros like OK,TRUE,FALSE,FAILURE . A friend who included this code as a library into his module...
4
by: Sweety | last post by:
plz reply, thanks in advance. bye
6
by: Walid | last post by:
Hey, I was trying some code with the .Net framework 1.1, and I found that the Interface name collisions is still not resolved in that version of the .net framework. I am refering to that piece...
17
by: sounak | last post by:
How could we get a macro name from a macro value such that in a header file #define a 100 #define b 200 now the source file will be such that the user gives 100 then the value is outputted as...
1
by: Scott McFadden | last post by:
C++ has some nice macros for obtaining the current function name, current source file, and current line number (__FUNCTION__, __FILE__, __LINE__). Does C# have any comparable MACROS?
27
by: Cephalobus_alienus | last post by:
Hello, I know that macros are evil, but I recently came across a problem that I couldn't figure out how to solve with templates. I wanted to create a set of singleton event objects, and wrote...
45
by: Zytan | last post by:
Shot in the dark, since I know C# doesn't have macros, and thus can't have a stringizer operator, but I know that you can get the name of enums as strings, so maybe you can do the same with an...
2
by: Tyno Gendo | last post by:
I'm writing a test "modular site". So far I have created an App class, a Module Manager class and a couple of test modules. The Manager looks in a directory called 'modules' and then for every...
5
by: Markus Dehmann | last post by:
Do I have to handle hash collisions in a hash_set myself? I did a test in which I use find() to look for objects in a hash_set. These objects are definitely not contained, but find() sometimes...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 7 Feb 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:30 (7.30PM). In this month's session, the creator of the excellent VBE...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: Aftab Ahmad | last post by:
Hello Experts! I have written a code in MS Access for a cmd called "WhatsApp Message" to open WhatsApp using that very code but the problem is that it gives a popup message everytime I clicked on...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
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...

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.