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

Macro that expand differently depending on the function calling it.

Hi,

Lets say I want to define a generic macro to swap bytes in a integer:
#define swapbytes(x) ...
I have several implementation of the macros, one is generic C, the
other one will be an optimized assembly version for a specific
architecture.

So I do something like that in swapbytes.h:

#ifdef __SOME_IMPLEMENTATION_SPECIFIC_MACRO__
#define swapbytes(x) \
... some implementation defined assembly crap...
#else
#define swapbytes(x) \
... some generic C code ...
#endif

This works well and I can extend this to support many different
implementation dependent optimizations: MIPS, ARM, x86,...

Now i have an additional issue. In some case, I have two functions in
the same source files that requires two different implementations of
the macro. An example of such case is when you deal with arm thumb or
mips16 instruction set. Some implementation allows you to mix both
types of code, but my swapbytes macro would needs to be different for
both of them.

Is there any way to handle that while still keeping a generic include
file ?

Thanks

-- Fabrice

PS: If you think this is off-topic because I mention mips16 and thumb,
dont even bother replying.I think the C standard was designed to cope
with implementation specific extensions and issues like this.

Oct 31 '07 #1
12 1527
On Wed, 31 Oct 2007 00:53:34 -0000, Fabrice
<fa*************@gmail.comwrote in comp.lang.c:
Hi,

Lets say I want to define a generic macro to swap bytes in a integer:
#define swapbytes(x) ...
I have several implementation of the macros, one is generic C, the
other one will be an optimized assembly version for a specific
architecture.

So I do something like that in swapbytes.h:

#ifdef __SOME_IMPLEMENTATION_SPECIFIC_MACRO__
#define swapbytes(x) \
... some implementation defined assembly crap...
#else
#define swapbytes(x) \
... some generic C code ...
#endif

This works well and I can extend this to support many different
implementation dependent optimizations: MIPS, ARM, x86,...

Now i have an additional issue. In some case, I have two functions in
the same source files that requires two different implementations of
the macro. An example of such case is when you deal with arm thumb or
mips16 instruction set. Some implementation allows you to mix both
types of code, but my swapbytes macro would needs to be different for
both of them.

Is there any way to handle that while still keeping a generic include
file ?

Thanks

-- Fabrice

PS: If you think this is off-topic because I mention mips16 and thumb,
dont even bother replying.I think the C standard was designed to cope
with implementation specific extensions and issues like this.
If you can provide proof from an Internationally recognized court of
law that has granted you supreme dictatorial powers over comp.lang.c,
and furthermore provide proof of that court's legal jurisdiction in
doing so, then you might attempt to forbid people who might dislike
your off-topic question from replying.

But I doubt if that would stop them. It certainly wouldn't stop me.

As for your incorrect belief about the C standard, and it is
incorrect, who gives a piece of bovine excrement?

*plonk*

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
Oct 31 '07 #2
Fabrice wrote:
Hi,

Lets say I want to define a generic macro to swap bytes in a integer:
#define swapbytes(x) ...
I have several implementation of the macros, one is generic C, the
other one will be an optimized assembly version for a specific
architecture.

So I do something like that in swapbytes.h:

#ifdef __SOME_IMPLEMENTATION_SPECIFIC_MACRO__
#define swapbytes(x) \
... some implementation defined assembly crap...
#else
#define swapbytes(x) \
... some generic C code ...
#endif

This works well and I can extend this to support many different
implementation dependent optimizations: MIPS, ARM, x86,...

Now i have an additional issue. In some case, I have two functions in
the same source files that requires two different implementations of
the macro. An example of such case is when you deal with arm thumb or
mips16 instruction set. Some implementation allows you to mix both
types of code, but my swapbytes macro would needs to be different for
both of them.
Why not just uses another macro, or better still, functions?

--
Ian Collins.
Oct 31 '07 #3
Fabrice <fabrice.gaut...@gmail.comwrote:
Lets say I want to define a generic macro to swap bytes
in a integer:
#define swapbytes(x) ...
I have several implementation of the macros, one is
generic C, the other one will be an optimized assembly
version for a specific architecture.

So I do something like that in swapbytes.h:

#ifdef __SOME_IMPLEMENTATION_SPECIFIC_MACRO__
#define swapbytes(x) \
... some implementation defined assembly crap...
#else
#define swapbytes(x) \
... some generic C code ...
#endif

This works well and I can extend this to support many
different implementation dependent optimizations: MIPS,
ARM, x86,...

Now i have an additional issue. In some case, I have two
functions in the same source files that requires two
different implementations of the macro.
So use two macros.

#define swapbytes_special(a,b) ...

#if blah
#define swapbytes(a,b) swapbytes_special(a,b)
#elif ...
#define swapbytes(a,b) ...
#elif ...
#define swapbytes(a,b) ...
....
#endif

void foo() { ...swapbytes_special(a,b); ... }
void bar() { ...swapbytes(a,b); ...}

<snip>
PS: If you think this is off-topic because I mention
mips16 and thumb, dont even bother replying.
If it's off topic, don't bother posting. That way,
everyone wins.
I think the C standard was designed to cope with
implementation specific extensions and issues like
this.
Of course it is. But that doesn't mean that comp.lang.c
is the place to discus those extensions.

--
Peter

Oct 31 '07 #4
Fabrice wrote:
Hi,

Lets say I want to define a generic macro to swap bytes in a integer:
#define swapbytes(x) ...
I have several implementation of the macros, one is generic C, the
other one will be an optimized assembly version for a specific
architecture.

So I do something like that in swapbytes.h:

#ifdef __SOME_IMPLEMENTATION_SPECIFIC_MACRO__
#define swapbytes(x) \
... some implementation defined assembly crap...
#else
#define swapbytes(x) \
... some generic C code ...
#endif

This works well and I can extend this to support many different
implementation dependent optimizations: MIPS, ARM, x86,...

Now i have an additional issue. In some case, I have two functions in
the same source files that requires two different implementations of
the macro. An example of such case is when you deal with arm thumb or
mips16 instruction set. Some implementation allows you to mix both
types of code, but my swapbytes macro would needs to be different for
both of them.

Is there any way to handle that while still keeping a generic include
file ?

Thanks

-- Fabrice

PS: If you think this is off-topic because I mention mips16 and thumb,
dont even bother replying.I think the C standard was designed to cope
with implementation specific extensions and issues like this.
#define swap(a,b) ((a)^=(b)^=(a)^=(b))
Doesn't get much simpler than that. Why do you need platform-specific
hoop-jumping?

--
Ark
Oct 31 '07 #5
Ark Khasin wrote:
#define swap(a,b) ((a)^=(b)^=(a)^=(b))
Doesn't get much simpler than that.
That expression is no good.

N869
6.5 Expressions
[#2] Between the previous and next sequence point an object
shall have its stored value modified at most once by the
evaluation of an expression.

--
pete
Oct 31 '07 #6
Ark Khasin <ak*****@macroexpressions.comwrites:
#define swap(a,b) ((a)^=(b)^=(a)^=(b))
Please read the FAQ.

3.3b: Here's a slick expression:

a ^= b ^= a ^= b

It swaps a and b without using a temporary.

A: Not portably, it doesn't. It attempts to modify the variable a
twice between sequence points, so its behavior is undefined.

For example, it has been reported that when given the code

int a = 123, b = 7654;
a ^= b ^= a ^= b;

the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.

See also questions 3.1, 3.8, 10.3, and 20.15c.

(I don't endorse using products from SCO.)
--
Ben Pfaff
http://benpfaff.org
Oct 31 '07 #7
Ben Pfaff wrote:
Ark Khasin <ak*****@macroexpressions.comwrites:
>#define swap(a,b) ((a)^=(b)^=(a)^=(b))

Please read the FAQ.

3.3b: Here's a slick expression:

a ^= b ^= a ^= b

It swaps a and b without using a temporary.

A: Not portably, it doesn't. It attempts to modify the variable a
twice between sequence points, so its behavior is undefined.

For example, it has been reported that when given the code

int a = 123, b = 7654;
a ^= b ^= a ^= b;

the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.

See also questions 3.1, 3.8, 10.3, and 20.15c.

(I don't endorse using products from SCO.)
OK. Got things wrong again. How about
#define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
?
But all in all, I agree with FAQ 10.3: "If you're consumed by a
passionate desire to solve this problem once and for all, please
reconsider; there are better problems worthier of your energies."
--
Ark
Nov 1 '07 #8

# OK. Got things wrong again. How about
# #define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)

Assume for example, that variable a is loaded in register R1, and
b in R2. On optimising compiler can potentially translate:

t = a; a = b; b = t;

into the assembly code:

No code at all, it simply relabels register R2 as a and R1 as b.
An optimiser could possibly realizes the exclusive ors are a swap,
or it might not, with three operations to do what it might have done
with zero operations if the intent of the programmer was clear.

# But all in all, I agree with FAQ 10.3: "If you're consumed by a
# passionate desire to solve this problem once and for all, please
# reconsider; there are better problems worthier of your energies."

Let the optimiser worry about cleverness. Write code that is obvious.

--
SM Ryan http://www.rawbw.com/~wyrmwif/
You hate people.
But I love gatherings. Isn't it ironic.
Nov 1 '07 #9
Ark Khasin wrote:
>
.... snip ...
>
OK. Got things wrong again. How about
#define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
?
But all in all, I agree with FAQ 10.3: "If you're consumed by a
passionate desire to solve this problem once and for all, please
reconsider; there are better problems worthier of your energies."
Fails. Try:

int a = 5;
swap(a, a);

results in a == 0

--
Chuck F (cbfalconer at maineline dot net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net>
--
Posted via a free Usenet account from http://www.teranews.com

Nov 1 '07 #10
CBFalconer wrote:
Ark Khasin wrote:
... snip ...
>OK. Got things wrong again. How about
#define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
?
But all in all, I agree with FAQ 10.3: "If you're consumed by a
passionate desire to solve this problem once and for all, please
reconsider; there are better problems worthier of your energies."

Fails. Try:

int a = 5;
swap(a, a);

results in a == 0
Arrgh! Which proves stealing is not good. Does FAQ 10.3 "If the values
are integers, a well-known trick using exclusive-OR could perhaps be
used" need revising?
--
Ark
Nov 1 '07 #11
Ark Khasin said:
CBFalconer wrote:
>Ark Khasin wrote:
... snip ...
>>OK. Got things wrong again. How about
#define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
?
But all in all, I agree with FAQ 10.3: "If you're consumed by a
passionate desire to solve this problem once and for all, please
reconsider; there are better problems worthier of your energies."

Fails. Try:

int a = 5;
swap(a, a);

results in a == 0
Arrgh! Which proves stealing is not good. Does FAQ 10.3 "If the values
are integers, a well-known trick using exclusive-OR could perhaps be
used" need revising?
No, you just need to read it more carefully next time. It actually *tells*
you that the XOR "trick" doesn't work, in the very sentence you quote,
which reads in full as follows:

"If the values are integers, a well-known trick using exclusive-OR could
perhaps be used, but it will not work for floating-point values or
pointers, or if the two values are the same variable."

The whole thrust of FAQ 10.3 is "please don't do this stupid thing", and
anyone taking about 40% of *one* sentence of the reply out of context and
using it to justify or excuse broken code is guilty of reading with their
brain switched off.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 1 '07 #12
Ark Khasin <ak*****@macroexpressions.comwrites:
Ben Pfaff wrote:
>Ark Khasin <ak*****@macroexpressions.comwrites:
>>#define swap(a,b) ((a)^=(b)^=(a)^=(b))
Please read the FAQ.
3.3b: Here's a slick expression:
a ^= b ^= a ^= b
It swaps a and b without using a temporary.
A: Not portably, it doesn't. It attempts to modify the variable a
twice between sequence points, so its behavior is undefined.
For example, it has been reported that when given the code
int a = 123, b = 7654;
a ^= b ^= a ^= b;
the SCO Optimizing C compiler (icc) sets b to 123 and a to 0.
See also questions 3.1, 3.8, 10.3, and 20.15c.
(I don't endorse using products from SCO.)
OK. Got things wrong again. How about
#define swap(a,b) do{(a)^=(b); (b)^=(a); (a)^=(b);}while(0)
?
[...]

Better, but still not good.

The "do { ... } while(0)" trick isn't needed in this case, since
everything in the expansion is just an expression (or would be if you
dropped the semicolons). You could just write:

#define swap(a,b) ((a)^=(b), (b)^=(a), (a)^=(b))

or, preferably:

#define SWAP(a,b) ((a)^=(b), (b)^=(a), (a)^=(b))

That does address the sequence-point issue.

But try using to swap floating-point variables. And it quietly fails
if you try to swap a variable with itself, something that could happen
accidentally if you do something like SWAP(array[i], array[j]) or
SWAP(*p1, *p2). Finally, it's not inconceivable that xor'ing two
signed integer values could do odd things on some systems (bitwise
operations on signed integers make me nervous).

The way to swap two variables is to use a temporary:

tmp = x;
x = y;
y = tmp;

This is simple enough that it's probably not worth the effort to
encapsulate it. Just write the three assignments where you need them.

(It would be nice if C allowed multiple values to be assigned, so you
could write something like ``(x, y) = (y, x)'', but it doesn't.)

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 1 '07 #13

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

Similar topics

25
by: Andrew Dalke | last post by:
Here's a proposed Q&A for the FAQ based on a couple recent threads. Appropriate comments appreciated X.Y: Why doesn't Python have macros like in Lisp or Scheme? Before answering that, a...
2
by: Johan | last post by:
Hi, Can somebody help me with this problem : I have the following member functions #define FUNC(x) get##() class A { the declarations etc, etc.
7
by: Newbie_sw2003 | last post by:
Where should I use them? I am giving you my understandings. Please correct me if I am wrong: MACRO: e.g.:#define ref-name 99 The code is substituted by the MACRO ref-name. So no overhead....
14
by: Michael B Allen | last post by:
I just noticed that doing something like the following may fail because it can overwrite u->size before it's evaluated. memcpy(u, buf, u->size); Is it legit that this is a macro as opposed to...
8
by: David | last post by:
Hi, I am using header file for driver so Can I define macro to call Kernel function ? What are the generatl rules for defining macro. - David
37
by: junky_fellow | last post by:
hi guys, Can you please suggest that in what cases should a macro be preferred over inline function and viceversa ? Is there any case where using a macro will be more efficient as compared to...
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...
5
by: Peng Yu | last post by:
Hi, I want a macro #expand that can be expanded to one of the following depending on its argument f(i1) f(i1, i2) f(i1, i2, i3) ...
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: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

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.